task-ledger 1.3.10 → 1.3.12
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/SKILL.md +2 -2
- package/package.json +1 -1
- package/scripts/ledgerkit/shell/cli.py +45 -22
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-ledger
|
|
3
3
|
description: 本地任务台账,跨会话记录在办任务的归属、进度与起止。当用户要登记一件新的事(新建任务 / 建个坑 / 这活我领了)、记录已有任务的进展(接着做 / 记一条进展 / 这轮先记下)、查看任务状态或历史(现在该做什么 / 这活谁在做 / 上周做过什么)、给任务结案或退回(做完了 / 验收通过 / 不做了 / 退回待认领)、整理标签或检查台账一致性时加载;只是改代码、讨论方案时不要用。
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.12
|
|
5
5
|
allowed-tools: Read,Edit,Bash,Grep
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -45,7 +45,7 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
45
45
|
| `--claim <uuid>` | 认领名册里已有的 uuid(名字一起复制) |
|
|
46
46
|
| `--new --name "…"` | 新建身份:生成 uuid + 名字 |
|
|
47
47
|
|
|
48
|
-
干什么:写本机身份文件(`~/.taskledger/identity.json`),**一台机器只一次**,与台账无关。在终端里**裸跑 `init` 即交互式选择框**:读当前仓库名册,用**上下箭头**移动、**Enter**
|
|
48
|
+
干什么:写本机身份文件(`~/.taskledger/identity.json`),**一台机器只一次**,与台账无关。在终端里**裸跑 `init` 即交互式选择框**:读当前仓库名册,用**上下箭头**移动、**Enter** 认领某个身份,末尾「+ 新建身份」可输入新用户名自建;名册为空则直接让你输入用户名;全程要真终端。`--claim <uuid>` / `--new --name "<名字>"` 也只接受真终端,agent 的无终端调用会被脚本拒绝。
|
|
49
49
|
|
|
50
50
|
### new — 建任务
|
|
51
51
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-ledger",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.12",
|
|
4
4
|
"description": "Task-ledger skill for coding agents: per-workspace progress tracking (ledger/pool.json + owners/<hash>.json shards + owners.json index, history, worklog) driven by a CLI script. Standalone install for CodeBuddy and other agents; also bundled inside the dsh-task-ledger DSH plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"skill",
|
|
@@ -286,12 +286,29 @@ def _print_init_result(res: dict) -> None:
|
|
|
286
286
|
|
|
287
287
|
|
|
288
288
|
def _select_identity(opts: list[dict], *, title: str) -> tuple[str, int | None]:
|
|
289
|
-
"""
|
|
289
|
+
"""交互式选身份:↑/↓ 移动、Enter 确认、Ctrl-C 取消,末尾「+ 新建身份」。
|
|
290
|
+
|
|
290
291
|
返回 (kind, index):kind∈{claim,new,cancel};claim/new 时 index 为候选项下标。
|
|
291
|
-
TTY
|
|
292
|
+
TTY 下用 raw 键盘 + 原地重绘(不整屏清屏、不动滚动条);不支持时退回编号输入。
|
|
293
|
+
仅在 TTY 调用。
|
|
292
294
|
"""
|
|
293
295
|
entries = list(opts) + [{"new": True}]
|
|
294
296
|
n = len(entries)
|
|
297
|
+
height = n + 4 # 标题 + 空行 + n 个选项 + 空行 + 提示
|
|
298
|
+
|
|
299
|
+
def _frame(sel: int) -> list[str]:
|
|
300
|
+
rows = ["\x1b[1;36m" + title + "\x1b[0m", ""]
|
|
301
|
+
for i, e in enumerate(entries):
|
|
302
|
+
label = (
|
|
303
|
+
"+ 新建身份(自己输入名字)"
|
|
304
|
+
if e.get("new")
|
|
305
|
+
else f"@{e['name']} {e['uuid']}"
|
|
306
|
+
)
|
|
307
|
+
rows.append(
|
|
308
|
+
"\x1b[7m ❯ " + label + " \x1b[0m" if i == sel else " " + label
|
|
309
|
+
)
|
|
310
|
+
rows += ["", "\x1b[2m ↑/↓ 移动 Enter 确认 Ctrl-C 退出\x1b[0m"]
|
|
311
|
+
return rows
|
|
295
312
|
|
|
296
313
|
try:
|
|
297
314
|
fd = sys.stdin.fileno()
|
|
@@ -302,25 +319,23 @@ def _select_identity(opts: list[dict], *, title: str) -> tuple[str, int | None]:
|
|
|
302
319
|
|
|
303
320
|
old = termios.tcgetattr(fd)
|
|
304
321
|
sel = 0
|
|
322
|
+
drew = False
|
|
323
|
+
result: tuple[str, int | None] = ("cancel", None)
|
|
305
324
|
try:
|
|
306
325
|
tty.setraw(fd)
|
|
326
|
+
sys.stdout.write("\x1b[?25l") # 隐藏光标
|
|
307
327
|
while True:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
sys.stdout.write(" \x1b[7m ❯ " + label + " \x1b[0m\n")
|
|
318
|
-
else:
|
|
319
|
-
sys.stdout.write(" " + label + "\n")
|
|
320
|
-
sys.stdout.write(
|
|
321
|
-
"\n \x1b[2m↑/↓ 移动 · Enter 确认 · Ctrl-C 退出\x1b[0m\n"
|
|
322
|
-
)
|
|
328
|
+
rows = _frame(sel)
|
|
329
|
+
if drew:
|
|
330
|
+
sys.stdout.write(f"\x1b[{height}A") # 回到本块第一行
|
|
331
|
+
else:
|
|
332
|
+
sys.stdout.write("\r\n") # 从新行开始,避开 shell 提示
|
|
333
|
+
drew = True
|
|
334
|
+
for row in rows:
|
|
335
|
+
# raw 模式下 \n 不回行首,必须显式 \r\n,否则逐行右移
|
|
336
|
+
sys.stdout.write("\r\x1b[K" + row + "\r\n")
|
|
323
337
|
sys.stdout.flush()
|
|
338
|
+
|
|
324
339
|
ch = sys.stdin.read(1)
|
|
325
340
|
if ch == "\x1b":
|
|
326
341
|
nxt = sys.stdin.read(1)
|
|
@@ -331,24 +346,32 @@ def _select_identity(opts: list[dict], *, title: str) -> tuple[str, int | None]:
|
|
|
331
346
|
elif k == "B":
|
|
332
347
|
sel = (sel + 1) % n
|
|
333
348
|
elif ch in ("\r", "\n"):
|
|
334
|
-
|
|
349
|
+
result = (
|
|
350
|
+
("new", None) if entries[sel].get("new") else ("claim", sel)
|
|
351
|
+
)
|
|
352
|
+
break
|
|
335
353
|
elif ch == "\x03": # Ctrl-C
|
|
336
|
-
|
|
354
|
+
result = ("cancel", None)
|
|
355
|
+
break
|
|
337
356
|
finally:
|
|
357
|
+
sys.stdout.write("\x1b[?25h") # 显示光标
|
|
358
|
+
if drew:
|
|
359
|
+
# 原地擦掉菜单块(不滚动主屏),光标留在块首,结果从这里打印
|
|
360
|
+
sys.stdout.write(f"\x1b[{height}A\r\x1b[J")
|
|
338
361
|
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
|
339
|
-
sys.stdout.write("\x1b[2J\x1b[H")
|
|
340
362
|
sys.stdout.flush()
|
|
363
|
+
return result
|
|
341
364
|
except (OSError, ImportError):
|
|
342
365
|
print(title)
|
|
343
366
|
for i, o in enumerate(opts, 1):
|
|
344
367
|
print(f" {i}. @{o['name']} {o['uuid']}")
|
|
345
|
-
print(f" {n}.
|
|
368
|
+
print(f" {n}. + 新建身份")
|
|
346
369
|
while True:
|
|
347
370
|
try:
|
|
348
371
|
c = input(f"选编号(1-{n}):").strip()
|
|
349
372
|
except (EOFError, KeyboardInterrupt):
|
|
350
373
|
return ("cancel", None)
|
|
351
|
-
if c.lower()
|
|
374
|
+
if c.lower() in ("n", "new"):
|
|
352
375
|
return ("new", None)
|
|
353
376
|
try:
|
|
354
377
|
idx = int(c) - 1
|