@lumoai/cli 1.20.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lumo
3
- description: 'Use the Lumo CLI to load task context, manage session bindings, and run tasks / projects / milestones / sprints / docs / memory from the terminal. Activate when: the user mentions a Lumo task identifier (LUM-42 etc.), asks to load task background/context, wants to bind/check/detach a Claude Code session''s task, is about to start work on a task, or wants to create/update/list/show/comment on tasks, projects, milestones, sprints, documents, artifacts, Figma links, or memory. Triggers on: "LUM-", "task context", "load context", "session start", "session attach", "session status", "session detach", "which task", "what task am I on", "work on LUM", "session wrap", "wrap up session", "进度评论", "卡住检测", "fragment usage vote", "mark used fragments", "which fragments did I use", "--used", "上下文使用投票", "标记用过的记忆", "create task", "new task", "file a task", "list tasks", "my tasks", "show task", "view task", "comment on task", "update task", "change task status", "rename task", "reassign task", "mark task as done", "lumo next", "next task", "what should I work on", "推荐下一个任务", "list projects", "what projects", "milestone", "里程碑", "list/create/update/delete/show milestone", "set milestone", "attach/unbind milestone", "tasks in milestone", "search milestones", "find milestone", "milestone health", "at-risk", "overdue", "archive/unarchive milestone", "归档里程碑", "milestone summary", "里程碑复盘", "reorder/move milestone", "排序里程碑", "milestone add/remove", "挂任务到里程碑", "auth login", "log in", "logout", "sign out", "switch account", "whoami", "who am I", "current workspace", "登录", "切换账号", "create/update/list/show/delete doc", "write doc", "写文档", "新建文档", "修改文档", "查看文档", "bind/unbind doc", "把文档关联到任务", "doc scope", "personal/workspace doc", "tag", "add/remove tag", "标签", "share/unshare doc", "分享文档", "doc share-list", "viewer/editor/manager", "doc tree", "doc move", "move/reparent doc", "移动文档", "sprint", "冲刺", "迭代", "create/list/show/update/delete sprint", "start/close sprint", "开始/关闭冲刺", "add to sprint", "active sprints", "sprint summary", "冲刺总结", "把任务挂到冲刺", "sprint health", "sprint risk", "is this sprint at risk", "冲刺风险", "冲刺健康度", "sprint blockers", "冲刺阻塞", "lumo update", "upgrade lumo", "升级 lumo", "new lumo version", "lumo setup", "install lumo skill/hooks", "wire up lumo", "set up lumo", "安装 lumo", "配置 lumo", "task artifact", "artifact add/list/show/update/rm", "spec artifact", "record/attach spec", "attach plan", "记录 spec", "查看 artifact", figma, attach figma, figma link, 关联 figma, 设计稿, figma design, "memory", "记忆", "remember", "record a memory", "记一条", "promote memory", "promote to project", "沉淀", "task/project memory", "retrieval", "取全文", "拉全文", "task slack show", "看 thread", "show slack thread", "task web show", "web 正文", "task figma context", "figma metadata", "task comments list", "list comments", "看评论", "task pr show", "查看 PR", "show pr", "PR 详情", "import google doc", "sync google doc", "google drive", "doc import-gdoc", "doc sync", "导入/同步 google 文档", "mark blocked", "blocked tag", "标记 blocked", "stuck", "repeatedly failing", "worktree", "git worktree", "并行 worktree", "scaffold worktree", "新建 worktree", "node_modules 软链", "worktree 隔离", "lumo worktree add/rm/list", "task lineage", "lineage", "causal trail", "审计", "因果链", "成本归因", "trace context".'
3
+ description: 'Use the Lumo CLI to load task context, manage session bindings, and run tasks / projects / milestones / sprints / docs / memory from the terminal. Activate when: the user mentions a Lumo task identifier (LUM-42 etc.), asks to load task background/context, wants to bind/check/detach a Claude Code session''s task, is about to start work on a task, or wants to create/update/list/show/comment on tasks, projects, milestones, sprints, documents, artifacts, Figma links, or memory. Triggers on: "LUM-", "task context", "load context", "session start", "session attach", "session status", "session detach", "which task", "what task am I on", "work on LUM", "session wrap", "wrap up session", "进度评论", "卡住检测", "fragment usage vote", "mark used fragments", "which fragments did I use", "--used", "上下文使用投票", "标记用过的记忆", "create task", "new task", "file a task", "list tasks", "my tasks", "show task", "view task", "comment on task", "update task", "change task status", "rename task", "reassign task", "mark task as done", "lumo next", "next task", "what should I work on", "推荐下一个任务", "list projects", "what projects", "milestone", "里程碑", "list/create/update/delete/show milestone", "set milestone", "attach/unbind milestone", "tasks in milestone", "search milestones", "find milestone", "milestone health", "at-risk", "overdue", "archive/unarchive milestone", "归档里程碑", "milestone summary", "里程碑复盘", "reorder/move milestone", "排序里程碑", "milestone add/remove", "挂任务到里程碑", "auth login", "log in", "logout", "sign out", "switch account", "whoami", "who am I", "current workspace", "登录", "切换账号", "create/update/list/show/delete doc", "write doc", "写文档", "新建文档", "修改文档", "查看文档", "bind/unbind doc", "把文档关联到任务", "doc scope", "personal/workspace doc", "tag", "add/remove tag", "标签", "share/unshare doc", "分享文档", "doc share-list", "viewer/editor/manager", "doc tree", "doc move", "move/reparent doc", "移动文档", "sprint", "冲刺", "迭代", "create/list/show/update/delete sprint", "start/close sprint", "开始/关闭冲刺", "add to sprint", "active sprints", "sprint summary", "冲刺总结", "把任务挂到冲刺", "sprint health", "sprint risk", "is this sprint at risk", "冲刺风险", "冲刺健康度", "sprint blockers", "冲刺阻塞", "lumo update", "upgrade lumo", "升级 lumo", "new lumo version", "lumo setup", "install lumo skill/hooks", "wire up lumo", "set up lumo", "安装 lumo", "配置 lumo", "task artifact", "artifact add/list/show/update/rm", "spec artifact", "record/attach spec", "attach plan", "记录 spec", "查看 artifact", figma, attach figma, figma link, 关联 figma, 设计稿, figma design, "memory", "记忆", "remember", "record a memory", "记一条", "promote memory", "promote to project", "沉淀", "task/project memory", "retrieval", "取全文", "拉全文", "task slack show", "看 thread", "show slack thread", "task web show", "web 正文", "task figma context", "figma metadata", "task comments list", "list comments", "看评论", "task pr show", "查看 PR", "show pr", "PR 详情", "import google doc", "sync google doc", "google drive", "doc import-gdoc", "doc sync", "导入/同步 google 文档", "mark blocked", "blocked tag", "标记 blocked", "stuck", "repeatedly failing", "worktree", "git worktree", "并行 worktree", "scaffold worktree", "新建 worktree", "node_modules 软链", "worktree 隔离", "lumo worktree add/rm/list", "task lineage", "lineage", "causal trail", "审计", "因果链", "成本归因", "trace context", "--signal", "usage signal health", "auto usage audit", "自动使用审计", "signal-health".'
4
4
  ---
5
5
 
6
6
  ## Prerequisites
@@ -49,7 +49,7 @@ The command catalog below is a **map**: it lists every command grouped by domain
49
49
  - `lumo task figma context <id> <linkId>` — Figma link metadata (v1)
50
50
  - `lumo task comments list <id>` — full comment thread (read-only; ≠ `task comment`)
51
51
  - `lumo task pr show <id> <number>` — synced PR metadata (v1)
52
- - `lumo task lineage <id>` — show the causal trail: fragments that fed the task + each one's outcome + the run's token/loop cost (read-only audit view)
52
+ - `lumo task lineage <id>` — show the causal trail: fragments that fed the task + each one's outcome + the run's token/loop cost (read-only audit view); `lumo task lineage <id> --signal` also appends workspace-level usage signal-health (used distribution, per-session variance, used-vs-base merge rate)
53
53
 
54
54
  **Tasks** — see [tasks.md](references/tasks.md)
55
55
 
@@ -98,7 +98,7 @@ The command catalog below is a **map**: it lists every command grouped by domain
98
98
 
99
99
  - `lumo session attach <id>` — bind this session to a task (then run `task context`)
100
100
  - `lumo session status` / `lumo session detach` — show / clear binding
101
- - `lumo session wrap [--yes] [--dry-run] [--used <indices>]` — end-of-session panel: progress comment + memory review + fragment-usage vote (`--used`, LUM-300) + blocked-tag prompt
101
+ - `lumo session wrap [--yes] [--dry-run] [--used <indices>]` — end-of-session panel: progress comment + memory review + fragment-usage vote (`--used`, LUM-300) + blocked-tag prompt. Usage is now also audited automatically when a task reaches DONE (evidence-gated, true-only — confident fragments marked used, the rest left NULL); `session wrap --used` remains the manual override and takes precedence for a session.
102
102
  - Git-suggest at session start (suggests `session attach`, never auto-binds) + Layer-2 project-memory review — see the reference
103
103
 
104
104
  **Worktrees (local dev tooling)** — see [worktree.md](references/worktree.md)
@@ -44,7 +44,7 @@ developer could learn from the source, git log, or docs. When unsure, don't.
44
44
 
45
45
  ### Which category
46
46
 
47
- - `trap` — a pitfall. Describe the PROBLEM ONLY (`--trigger`, `--outcome`); put any fix in a separate `procedural`.
47
+ - `trap` — a pitfall. Describe the problem (`--trigger`, `--outcome`); put a **one-line fix** inline via `--workaround`. Only when the fix is a genuine multi-step workflow, omit `--workaround` and add a separate `procedural` instead — never both (a `procedural` that just restates a trap's `--workaround` is a double-write).
48
48
  - `decision` — an engineering decision (`--what` + `--why`, optional `--alternatives`/`--implications`).
49
49
  - `convention` — a team rule (`--rule` + `--applies` = where it applies).
50
50
  - `procedural` — a reusable workflow (`--workflow` + `--trigger` + `--step`…).
@@ -114,14 +114,14 @@ lumo task pr show LUM-42 128
114
114
  Read-only audit view over the task's `LineageEdge` rows. Given a task
115
115
  identifier (`LUM-N`), prints the causal trail:
116
116
 
117
- - **Totals banner** — distinct runs/sessions, fragment count, edge count,
117
+ - **Totals banner** — distinct sessions, fragment count, edge count,
118
118
  total tokens (input/output/cache split) and loops, and the outcome
119
119
  distribution.
120
- - **One block per run/session** — the group's cost shown **once** (token/loop),
120
+ - **One block per session** — the group's cost shown **once** (token/loop),
121
121
  the date it consumed context, then each context fragment as
122
122
  `[OUTCOME] TYPE — <source label>`, plus a per-group outcome summary.
123
123
 
124
- Cost is attributed once per run/session (a run that injected many fragments is
124
+ Cost is attributed once per session (a session that injected many fragments is
125
125
  not double-counted). Fragment ids are canonical — MEMORY fragments survive
126
126
  consolidation drift.
127
127
 
@@ -2,10 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.taskLineage = taskLineage;
4
4
  exports.formatLineageMarkdown = formatLineageMarkdown;
5
+ exports.formatSignalHealth = formatSignalHealth;
5
6
  const config_1 = require("../lib/config");
6
7
  const api_1 = require("../lib/api");
7
8
  const sanitize_1 = require("../lib/sanitize");
8
- async function taskLineage(identifier) {
9
+ async function taskLineage(identifier, opts) {
9
10
  if (!identifier) {
10
11
  console.error('Error: missing <identifier>. Usage: lumo task lineage <LUM-42>');
11
12
  return 1;
@@ -42,6 +43,26 @@ async function taskLineage(identifier) {
42
43
  }
43
44
  const data = (await res.json());
44
45
  process.stdout.write(formatLineageMarkdown(data));
46
+ if (opts?.signal) {
47
+ const signalUrl = `${(0, api_1.trimTrailingSlash)(apiUrl)}/api/lineage/signal`;
48
+ let signalRes;
49
+ try {
50
+ signalRes = await fetch(signalUrl, {
51
+ headers: { Authorization: `Bearer ${creds.token}` },
52
+ });
53
+ }
54
+ catch (err) {
55
+ const msg = err instanceof Error ? err.message : String(err);
56
+ process.stderr.write(`Warning: could not fetch signal health (${msg})\n`);
57
+ return;
58
+ }
59
+ if (!signalRes.ok) {
60
+ process.stderr.write(`Warning: signal health fetch failed (HTTP ${signalRes.status})\n`);
61
+ return;
62
+ }
63
+ const signalJson = (await signalRes.json());
64
+ process.stdout.write('\n' + formatSignalHealth(signalJson) + '\n');
65
+ }
45
66
  }
46
67
  /** Deterministic thousands separator (no locale dependency, test-stable). */
47
68
  function groupThousands(n) {
@@ -64,6 +85,9 @@ function fragmentOutcomeCounts(fragments) {
64
85
  c[f.outcome] += 1;
65
86
  return c;
66
87
  }
88
+ function usageMarker(used) {
89
+ return used === true ? '✓' : used === false ? '✗' : '·';
90
+ }
67
91
  /**
68
92
  * Render a LineageResponse as the audit-facing markdown trail. Pure function
69
93
  * (no clock / env) so the CLI output is deterministic and unit-testable.
@@ -75,7 +99,7 @@ function formatLineageMarkdown(data) {
75
99
  lines.push('');
76
100
  if (data.groups.length === 0) {
77
101
  lines.push('_No lineage edges recorded yet. Lineage is captured when a ' +
78
- "session-bound run consumes this task's context; once that happens " +
102
+ "bound session consumes this task's context; once that happens " +
79
103
  '(and a PR merges / the task closes), the causal trail and its cost ' +
80
104
  'will appear here._');
81
105
  lines.push('');
@@ -104,10 +128,23 @@ function formatLineageMarkdown(data) {
104
128
  }
105
129
  const summary = outcomeSummary(fragmentOutcomeCounts(g.fragments));
106
130
  lines.push(`**Fragments** (${g.fragments.length}${summary ? `: ${summary}` : ''}):`);
131
+ lines.push('_✓ used · · abstained · ✗ unused (manual)_');
107
132
  for (const f of g.fragments) {
108
- lines.push(`- [${f.outcome}] ${f.fragmentType} — ${(0, sanitize_1.sanitizeField)(f.sourceLabel)}`);
133
+ lines.push(`- ${usageMarker(f.used)} [${f.outcome}] ${f.fragmentType} — ${(0, sanitize_1.sanitizeField)(f.sourceLabel)}`);
109
134
  }
110
135
  lines.push('');
111
136
  }
112
137
  return lines.join('\n');
113
138
  }
139
+ function formatSignalHealth(h) {
140
+ const lines = ['', '## Signal health'];
141
+ lines.push(`- Distribution: used ${h.distribution.used} · null ${h.distribution.abstained} · false ${h.distribution.unused}`);
142
+ lines.push(`- Per-session variance: ${h.perSessionVariance.toFixed(2)} (${h.votedSessions} voted sessions)`);
143
+ if (h.usedMergeRate !== null && h.baseMergeRate !== null) {
144
+ lines.push(`- Used × outcome: merge-rate(used) ${Math.round(h.usedMergeRate * 100)}% vs base ${Math.round(h.baseMergeRate * 100)}%`);
145
+ }
146
+ else {
147
+ lines.push('- Used × outcome: insufficient resolved tasks');
148
+ }
149
+ return lines.join('\n');
150
+ }
@@ -313,7 +313,8 @@ taskPr
313
313
  task
314
314
  .command('lineage <identifier>')
315
315
  .description("Show the causal trail: which context fragments fed this task, each fragment's outcome, and the token/loop cost of the run that consumed it")
316
- .action(wrap(id => (0, task_lineage_1.taskLineage)(id)));
316
+ .option('--signal', 'Append usage-signal health section (fetches /api/lineage/signal)')
317
+ .action(wrap((id, options) => (0, task_lineage_1.taskLineage)(id, options)));
317
318
  const taskMemory = task
318
319
  .command('memory')
319
320
  .description('View and record memories scoped to a task');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumoai/cli",
3
- "version": "1.20.0",
3
+ "version": "1.20.1",
4
4
  "description": "Lumo CLI — manage tasks and sessions from the terminal",
5
5
  "license": "MIT",
6
6
  "author": "cli@uselumo.ai",