@lumoai/cli 1.24.0 → 1.25.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/assets/skill/SKILL.md
CHANGED
|
@@ -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 详情", "task deps", "dependency", "dependencies", "依赖", "依赖边", "blocked by", "blocker", "confirm dependency", "dismiss dependency", "确认依赖", "忽略依赖", "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 criteria", "criteria set", "criteria list", "acceptance criteria", "验收标准", "验收合约", "draft criteria", "草拟验收", "definition of done", "lumo verify", "verify task", "machine verification", "verification round", "机器验收", "自验", "验收轮", "claim done", "宣称完成", "--cause", "contract drift", "合约漂移", "task lineage", "lineage", "causal trail", "审计", "因果链", "成本归因", "trace context", "--signal", "usage signal health", "auto usage audit", "自动使用审计", "signal-health".'
|
|
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 详情", "task deps", "dependency", "dependencies", "依赖", "依赖边", "blocked by", "blocker", "confirm dependency", "dismiss dependency", "确认依赖", "忽略依赖", "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 criteria", "criteria set", "criteria list", "acceptance criteria", "验收标准", "验收合约", "draft criteria", "草拟验收", "definition of done", "lumo verify", "verify task", "machine verification", "verification round", "机器验收", "自验", "验收轮", "claim done", "宣称完成", "--cause", "contract drift", "合约漂移", "task status", "acceptance status", "验收进度", "验收状态", "verification history", "验收历史", "next actions", "还差什么", "unmet criteria", "未满足", "resume task", "恢复任务", "被打回", "current round", "第几轮", "task lineage", "lineage", "causal trail", "审计", "因果链", "成本归因", "trace context", "--signal", "usage signal health", "auto usage audit", "自动使用审计", "signal-health".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Prerequisites
|
|
@@ -26,7 +26,7 @@ The command catalog below is a **map**: it lists every command grouped by domain
|
|
|
26
26
|
| `task create/update/list/show/comment`, `next` | [references/tasks.md](references/tasks.md) |
|
|
27
27
|
| `task artifact*`, `task figma*` | [references/artifacts-figma.md](references/artifacts-figma.md) |
|
|
28
28
|
| `task criteria set/list`, drafting the acceptance contract | [references/criteria.md](references/criteria.md) |
|
|
29
|
-
| `verify` — machine verification loop, claim-done flow
|
|
29
|
+
| `verify`, `task status` — machine verification loop, claim-done flow, 自查/恢复 | [references/verify.md](references/verify.md) |
|
|
30
30
|
| `project list`, `milestone*` | [references/milestones.md](references/milestones.md) |
|
|
31
31
|
| `doc*` | [references/docs.md](references/docs.md) |
|
|
32
32
|
| `sprint*` | [references/sprints.md](references/sprints.md) |
|
|
@@ -79,6 +79,7 @@ The command catalog below is a **map**: it lists every command grouped by domain
|
|
|
79
79
|
**Verification(机器验收循环)** — see [verify.md](references/verify.md)
|
|
80
80
|
|
|
81
81
|
- `lumo verify [task] [--timeout <seconds>]` — run every MACHINE criterion's checkpointer locally, report one structured PASS/FAIL verdict per criterion to the server, print next actions. Defaults to the session-bound task. Round cap 3: an all-pass round moves the task to IN_REVIEW (agent stops there); a round-3 fail escalates to a human (stop retrying). **Run this before claiming a task is done.**
|
|
82
|
+
- `lumo task status [task] [--json]` — read-only acceptance self-check (no LLM, milliseconds): the contract with each criterion's latest verdict (REVIEW_ADDED provenance visible), verification history, current round, last round's failure reasons, and `nextActions` = the unmet criteria (the declarative "what's next" — no separate plan). Defaults to the session-bound task; `--json` emits a versioned payload (`version` field). **Run it first when resuming a task in a new session or after a verification round was rejected.**
|
|
82
83
|
|
|
83
84
|
**Artifacts & Figma** — see [artifacts-figma.md](references/artifacts-figma.md)
|
|
84
85
|
|
|
@@ -138,4 +139,6 @@ Typical flow when a user says "help me with LUM-42":
|
|
|
138
139
|
5. Begin working on the task
|
|
139
140
|
6. **Before claiming the work is done: run `lumo verify`** — the machine half of the acceptance loop. Fix failures and re-run (round cap 3). On all-pass the task moves to IN_REVIEW and you stop; never set DONE yourself after a verify loop — that adjudication is human-only. See [verify.md](references/verify.md)
|
|
140
141
|
|
|
142
|
+
**Status-first recovery:** when you pick a task back up — a new session resuming earlier work, or a task that came back after a rejected verification round / review findings — run `lumo task status` **before** re-reading code or planning. It tells you where the loop stands (current round, what passed, what's unmet and why, any REVIEW_ADDED criteria appended during review) so you don't redo finished work or miss the reason it bounced. See [verify.md](references/verify.md)
|
|
143
|
+
|
|
141
144
|
**Git-suggest at start:** when the session is unbound, session-start may infer the task from the git branch / recent commits and print a suggestion — `检测到 LUM-N … 运行 lumo session attach LUM-N 绑定。` — **without** binding. Confirm it's the right task, then run `lumo session attach <LUM-N>` yourself (binding only happens on an explicit attach). See [sessions.md](references/sessions.md) for the full session-start behavior.
|
|
@@ -70,3 +70,55 @@ Rounds are a hard budget of 3, not a retry loop. Between rounds, actually fix
|
|
|
70
70
|
the failures — re-running without changes burns a round and (at round 3)
|
|
71
71
|
pages a human. A FAIL round never changes task status; only an all-pass round
|
|
72
72
|
moves it (to IN_REVIEW, never further).
|
|
73
|
+
|
|
74
|
+
## lumo task status — the read half(自查入口)
|
|
75
|
+
|
|
76
|
+
`lumo task status [task] [--json]` is the read-only counterpart of the loop
|
|
77
|
+
(LUM-344): pure read, milliseconds, no LLM, never writes — running it costs
|
|
78
|
+
nothing and burns no round. Defaults to the session-bound task; an explicit
|
|
79
|
+
identifier overrides.
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
lumo task status # session-bound task
|
|
83
|
+
lumo task status LUM-42 # explicit task
|
|
84
|
+
lumo task status --json # versioned machine-readable payload
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### When to run it
|
|
88
|
+
|
|
89
|
+
**Status-first recovery:** run it FIRST — before re-reading code or
|
|
90
|
+
planning — whenever you:
|
|
91
|
+
|
|
92
|
+
- resume a task in a new session (yours or another agent's earlier work);
|
|
93
|
+
- come back after a verification round was rejected (`lumo verify` failed);
|
|
94
|
+
- were told the task bounced in review (REVIEW_ADDED criteria may have been
|
|
95
|
+
appended at the round they surfaced — they show up here automatically).
|
|
96
|
+
|
|
97
|
+
It answers "where does the loop stand": what already passed (don't redo it),
|
|
98
|
+
what's unmet and why (the exact failure tails), and how many rounds are left.
|
|
99
|
+
|
|
100
|
+
### What it prints
|
|
101
|
+
|
|
102
|
+
- Header: task identifier/title/status + `verification round N/3` (round 0 =
|
|
103
|
+
never verified) + an escalation warning when the machine loop is exhausted.
|
|
104
|
+
- **Criteria** — every criterion as `<glyph> <id> [TYPE] SOURCE@rN
|
|
105
|
+
statement` (✓ latest verdict passed / ✗ failed / ○ no verdict yet) with its
|
|
106
|
+
checkpointer and latest verdict line (evidence pointer on pass, failure
|
|
107
|
+
tail on fail). `REVIEW_ADDED@rN` provenance is visible per row.
|
|
108
|
+
- **History** — one line per recorded round: `rN · timestamp · X PASS / Y FAIL`.
|
|
109
|
+
- **Last round failures** — the most recent round's FAIL verdicts with their
|
|
110
|
+
rejection reasons (why the last round bounced).
|
|
111
|
+
- **Next actions** — the unmet criteria (latest verdict is not a pass:
|
|
112
|
+
failed or never verified, HUMAN ones included). This list IS the plan —
|
|
113
|
+
it is recomputed from the event log on every read, never maintained
|
|
114
|
+
separately. Empty + rounds recorded = awaiting human adjudication.
|
|
115
|
+
|
|
116
|
+
### --json contract
|
|
117
|
+
|
|
118
|
+
`--json` emits the full read model with a top-level `version` field
|
|
119
|
+
(currently `1`). The schema is versioned: breaking shape changes bump the
|
|
120
|
+
major; additive fields don't. Pin on `version` when scripting against it.
|
|
121
|
+
|
|
122
|
+
`status` reads; `verify` judges. Running status never starts a round, never
|
|
123
|
+
escalates, and never changes task state — loop rules (cap 3, IN_REVIEW on
|
|
124
|
+
all-pass, human-only DONE) live entirely in `lumo verify` and the server.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatTaskStatus = formatTaskStatus;
|
|
4
|
+
exports.taskStatus = taskStatus;
|
|
5
|
+
const config_1 = require("../lib/config");
|
|
6
|
+
const api_1 = require("../lib/api");
|
|
7
|
+
const resolve_bound_task_1 = require("../lib/resolve-bound-task");
|
|
8
|
+
const sanitize_1 = require("../lib/sanitize");
|
|
9
|
+
const REASON_TAIL = 400;
|
|
10
|
+
function tail(s, max) {
|
|
11
|
+
return s.length > max ? `…${s.slice(-max)}` : s;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Render the acceptance status as prose. Same row grammar as
|
|
15
|
+
* `criteria list` (`<id> [TYPE] SOURCE@rN statement`) with a verdict
|
|
16
|
+
* glyph in front — ✓ pass, ✗ fail, ○ no verdict yet — so REVIEW_ADDED
|
|
17
|
+
* provenance stays explicitly visible in every row.
|
|
18
|
+
*/
|
|
19
|
+
function formatTaskStatus(data) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
const t = data.task;
|
|
22
|
+
lines.push(`${t.identifier} ${(0, sanitize_1.sanitizeField)(t.title)}`);
|
|
23
|
+
const roundLabel = data.currentRound === 0
|
|
24
|
+
? 'no verification rounds yet'
|
|
25
|
+
: `verification round ${data.currentRound}/${data.maxRounds}`;
|
|
26
|
+
lines.push(`Status: ${t.status} · ${roundLabel}`);
|
|
27
|
+
if (data.escalated) {
|
|
28
|
+
lines.push('⚠ Escalated: the machine loop is exhausted — a human has been paged. Stop retrying lumo verify.');
|
|
29
|
+
}
|
|
30
|
+
if (data.criteria.length === 0) {
|
|
31
|
+
lines.push('');
|
|
32
|
+
lines.push(`No acceptance criteria on ${t.identifier} — draft 3–7 and submit with lumo task criteria set ${t.identifier} --file <criteria.json>`);
|
|
33
|
+
return lines.join('\n') + '\n';
|
|
34
|
+
}
|
|
35
|
+
lines.push('');
|
|
36
|
+
lines.push(`Criteria (${data.criteria.length} total, ${data.nextActions.length} unmet):`);
|
|
37
|
+
for (const c of data.criteria) {
|
|
38
|
+
const glyph = c.latestVerdict == null
|
|
39
|
+
? '○'
|
|
40
|
+
: c.latestVerdict.verdict === 'FAIL'
|
|
41
|
+
? '✗'
|
|
42
|
+
: '✓';
|
|
43
|
+
const provenance = `${c.source}@r${c.addedAtRound}`;
|
|
44
|
+
const evidence = c.evidenceRequired ? ' [evidence]' : '';
|
|
45
|
+
lines.push(` ${glyph} ${c.id} [${c.verifierType}] ${provenance}${evidence} ${(0, sanitize_1.sanitizeField)(c.statement)}`);
|
|
46
|
+
if (c.checkpointer) {
|
|
47
|
+
lines.push(` ↳ check: ${(0, sanitize_1.sanitizeField)(c.checkpointer)}`);
|
|
48
|
+
}
|
|
49
|
+
const v = c.latestVerdict;
|
|
50
|
+
if (v == null) {
|
|
51
|
+
lines.push(' (no verdict yet)');
|
|
52
|
+
}
|
|
53
|
+
else if (v.verdict === 'FAIL') {
|
|
54
|
+
const why = v.rejectionReason
|
|
55
|
+
? ` — ${(0, sanitize_1.sanitizeField)(tail(v.rejectionReason, REASON_TAIL))}`
|
|
56
|
+
: '';
|
|
57
|
+
lines.push(` ✗ FAIL@r${v.round}${why}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const evidencePart = v.evidencePointer
|
|
61
|
+
? ` · ${(0, sanitize_1.sanitizeField)(v.evidencePointer)}`
|
|
62
|
+
: '';
|
|
63
|
+
lines.push(` ✓ ${v.verdict}@r${v.round}${evidencePart}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (data.verificationHistory.length > 0) {
|
|
67
|
+
lines.push('');
|
|
68
|
+
lines.push('History:');
|
|
69
|
+
for (const h of data.verificationHistory) {
|
|
70
|
+
lines.push(` r${h.round} · ${h.recordedAt} · ${h.passed} PASS / ${h.failed} FAIL`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (data.lastRoundFailures.length > 0) {
|
|
74
|
+
lines.push('');
|
|
75
|
+
lines.push(`Last round (r${data.currentRound}) failures:`);
|
|
76
|
+
for (const f of data.lastRoundFailures) {
|
|
77
|
+
lines.push(` • ${(0, sanitize_1.sanitizeField)(f.statement)}`);
|
|
78
|
+
if (f.rejectionReason) {
|
|
79
|
+
lines.push(` why: ${(0, sanitize_1.sanitizeField)(tail(f.rejectionReason, REASON_TAIL))}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
lines.push('');
|
|
84
|
+
if (data.nextActions.length === 0) {
|
|
85
|
+
lines.push(data.currentRound > 0
|
|
86
|
+
? 'All criteria met by their latest verdicts — awaiting human adjudication.'
|
|
87
|
+
: 'Nothing unmet — but no verification has run; run `lumo verify` to judge the contract.');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lines.push(`Next actions (${data.nextActions.length} unmet):`);
|
|
91
|
+
for (const a of data.nextActions) {
|
|
92
|
+
lines.push(` • [${a.verifierType}] ${(0, sanitize_1.sanitizeField)(a.statement)}`);
|
|
93
|
+
if (a.checkpointer) {
|
|
94
|
+
lines.push(` check: ${(0, sanitize_1.sanitizeField)(a.checkpointer)}`);
|
|
95
|
+
}
|
|
96
|
+
if (a.rejectionReason) {
|
|
97
|
+
lines.push(` why: ${(0, sanitize_1.sanitizeField)(tail(a.rejectionReason, REASON_TAIL))}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (data.escalated) {
|
|
101
|
+
lines.push('Wait for human direction before touching these.');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const hasMachine = data.nextActions.some(a => a.verifierType === 'MACHINE');
|
|
105
|
+
const left = data.maxRounds - data.currentRound;
|
|
106
|
+
lines.push(hasMachine
|
|
107
|
+
? `Fix the unmet criteria, then run \`lumo verify\` (${left} round${left === 1 ? '' : 's'} left).`
|
|
108
|
+
: 'Remaining criteria are HUMAN-only — finish the work and hand off for human review.');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return lines.join('\n') + '\n';
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `lumo task status [task] [--json]` — the agent's read-only self-check
|
|
115
|
+
* (LUM-344): contract + latest verdicts + verification history + next
|
|
116
|
+
* actions, straight from the server's derived read model. Run it first when
|
|
117
|
+
* resuming a task in a new session or after a round was rejected. Defaults
|
|
118
|
+
* to the session-bound task; an explicit identifier overrides.
|
|
119
|
+
*/
|
|
120
|
+
async function taskStatus(identifier, options = {}) {
|
|
121
|
+
const creds = (0, config_1.readCredentials)();
|
|
122
|
+
if (!creds) {
|
|
123
|
+
console.error('Error: not logged in. Run `lumo auth login` first.');
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
const base = (0, api_1.trimTrailingSlash)((0, api_1.resolveAuthedApiUrl)(creds.apiUrl));
|
|
127
|
+
let taskId = identifier;
|
|
128
|
+
if (!taskId) {
|
|
129
|
+
taskId =
|
|
130
|
+
(await (0, resolve_bound_task_1.resolveBoundTaskIdentifier)(base, creds.token)) ?? undefined;
|
|
131
|
+
if (!taskId) {
|
|
132
|
+
console.error('Error: no task given and this session is not bound to one.\n' +
|
|
133
|
+
'Run `lumo task status <LUM-N>`, or bind first with `lumo session attach <LUM-N>`.');
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let res;
|
|
138
|
+
try {
|
|
139
|
+
res = await fetch(`${base}/api/tasks/${encodeURIComponent(taskId)}/status`, { headers: { Authorization: `Bearer ${creds.token}` } });
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
143
|
+
console.error(`Error: could not reach Lumo API (${msg})`);
|
|
144
|
+
return 1;
|
|
145
|
+
}
|
|
146
|
+
if (res.status === 401) {
|
|
147
|
+
console.error('Error: API key invalid or revoked. Run `lumo auth login`.');
|
|
148
|
+
return 1;
|
|
149
|
+
}
|
|
150
|
+
if (res.status === 404) {
|
|
151
|
+
console.error(`Error: task ${taskId} not found in workspace ${creds.workspaceSlug}`);
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
if (!res.ok) {
|
|
155
|
+
console.error(`Error: task status failed (HTTP ${res.status})`);
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
const data = (await res.json());
|
|
159
|
+
if (options.json) {
|
|
160
|
+
// JSON.stringify escapes control chars (…), so the payload is safe
|
|
161
|
+
// to emit raw — and consumers get byte-faithful server data.
|
|
162
|
+
process.stdout.write(JSON.stringify(data, null, 2) + '\n');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
process.stdout.write(formatTaskStatus(data));
|
|
166
|
+
}
|
package/dist/cli/src/index.js
CHANGED
|
@@ -53,6 +53,7 @@ const task_create_1 = require("./commands/task-create");
|
|
|
53
53
|
const task_update_1 = require("./commands/task-update");
|
|
54
54
|
const task_list_1 = require("./commands/task-list");
|
|
55
55
|
const task_show_1 = require("./commands/task-show");
|
|
56
|
+
const task_status_1 = require("./commands/task-status");
|
|
56
57
|
const task_comment_1 = require("./commands/task-comment");
|
|
57
58
|
const task_figma_add_1 = require("./commands/task-figma-add");
|
|
58
59
|
const task_figma_list_1 = require("./commands/task-figma-list");
|
|
@@ -249,6 +250,11 @@ task
|
|
|
249
250
|
.command('show <identifier>')
|
|
250
251
|
.description('Show a single task: title, status, priority, assignee, project, URL, description.')
|
|
251
252
|
.action(wrap(identifier => (0, task_show_1.taskShow)(identifier)));
|
|
253
|
+
task
|
|
254
|
+
.command('status [task]')
|
|
255
|
+
.description('Acceptance self-check (LUM-344): contract with latest verdicts, verification history, current round, and nextActions (unmet criteria). Read-only, no LLM. Defaults to the session-bound task. Run it first when resuming a task or after a verification round was rejected.')
|
|
256
|
+
.option('--json', 'Emit the versioned machine-readable payload (version field; breaking changes bump it)')
|
|
257
|
+
.action(wrap((taskArg, options) => (0, task_status_1.taskStatus)(taskArg, options)));
|
|
252
258
|
task
|
|
253
259
|
.command('comment <identifier> <body>')
|
|
254
260
|
.description('Add a comment to a task. Body is plain text — quote it to pass spaces or newlines.')
|