task-ledger 1.3.9 → 1.3.11
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 +17 -10
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.11
|
|
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.11",
|
|
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",
|
|
@@ -304,21 +304,23 @@ def _select_identity(opts: list[dict], *, title: str) -> tuple[str, int | None]:
|
|
|
304
304
|
sel = 0
|
|
305
305
|
try:
|
|
306
306
|
tty.setraw(fd)
|
|
307
|
+
sys.stdout.write("\x1b[?25l") # 隐藏光标
|
|
307
308
|
while True:
|
|
308
|
-
|
|
309
|
+
# 每帧整屏重绘(2J 清屏 + H 回家),位置无关,避免折行/行数错位
|
|
310
|
+
sys.stdout.write("\x1b[2J\x1b[H")
|
|
309
311
|
sys.stdout.write("\x1b[1;36m" + title + "\x1b[0m\n\n")
|
|
310
312
|
for i, e in enumerate(entries):
|
|
311
313
|
label = (
|
|
312
|
-
"
|
|
314
|
+
"+ 新建身份(自己输入名字)"
|
|
313
315
|
if e.get("new")
|
|
314
316
|
else f"@{e['name']} {e['uuid']}"
|
|
315
317
|
)
|
|
316
318
|
if i == sel:
|
|
317
|
-
sys.stdout.write("
|
|
319
|
+
sys.stdout.write("\x1b[7m ❯ " + label + " \x1b[0m\n")
|
|
318
320
|
else:
|
|
319
321
|
sys.stdout.write(" " + label + "\n")
|
|
320
322
|
sys.stdout.write(
|
|
321
|
-
"\n
|
|
323
|
+
"\n\x1b[2m ↑/↓ 移动 Enter 确认 Ctrl-C 退出\x1b[0m"
|
|
322
324
|
)
|
|
323
325
|
sys.stdout.flush()
|
|
324
326
|
ch = sys.stdin.read(1)
|
|
@@ -335,14 +337,15 @@ def _select_identity(opts: list[dict], *, title: str) -> tuple[str, int | None]:
|
|
|
335
337
|
elif ch == "\x03": # Ctrl-C
|
|
336
338
|
return ("cancel", None)
|
|
337
339
|
finally:
|
|
340
|
+
sys.stdout.write("\x1b[?25h") # 显示光标
|
|
341
|
+
sys.stdout.write("\x1b[2J\x1b[H") # 退出时清掉选择框,结果从顶部打印
|
|
338
342
|
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
|
339
|
-
sys.stdout.write("\x1b[2J\x1b[H")
|
|
340
343
|
sys.stdout.flush()
|
|
341
344
|
except (OSError, ImportError):
|
|
342
345
|
print(title)
|
|
343
346
|
for i, o in enumerate(opts, 1):
|
|
344
347
|
print(f" {i}. @{o['name']} {o['uuid']}")
|
|
345
|
-
print(f" {n}.
|
|
348
|
+
print(f" {n}. + 新建身份")
|
|
346
349
|
while True:
|
|
347
350
|
try:
|
|
348
351
|
c = input(f"选编号(1-{n}):").strip()
|
|
@@ -409,13 +412,13 @@ def _run_init(args: argparse.Namespace) -> int:
|
|
|
409
412
|
opts, title="这台机器还没初始化。选择你的身份,或新建一个:"
|
|
410
413
|
)
|
|
411
414
|
if kind == "cancel":
|
|
412
|
-
print("
|
|
413
|
-
return
|
|
415
|
+
print("\x1b[2m✕ 已取消初始化。随时可重跑 init 重新开始。\x1b[0m")
|
|
416
|
+
return 0
|
|
414
417
|
if kind == "new":
|
|
415
418
|
prompt_name = input("输入用户名:").strip()
|
|
416
419
|
if not prompt_name:
|
|
417
|
-
print("
|
|
418
|
-
return
|
|
420
|
+
print("\x1b[2m✕ 未输入用户名,已取消。\x1b[0m")
|
|
421
|
+
return 0
|
|
419
422
|
res = init_identity(repo, claim=None, new=True, name=prompt_name)
|
|
420
423
|
else:
|
|
421
424
|
res = init_identity(
|
|
@@ -431,6 +434,10 @@ def _run_init(args: argparse.Namespace) -> int:
|
|
|
431
434
|
except (ValueError, IndexError):
|
|
432
435
|
render.fail_message(Fail("输入无效,初始化已取消。"))
|
|
433
436
|
return BUSINESS
|
|
437
|
+
except (KeyboardInterrupt, EOFError):
|
|
438
|
+
# 中途 Ctrl-C / Ctrl-D:平静取消,不抛栈、干净退出
|
|
439
|
+
print("\x1b[2m✕ 已取消初始化。随时可重跑 init 重新开始。\x1b[0m")
|
|
440
|
+
return 0
|
|
434
441
|
_print_init_result(res)
|
|
435
442
|
return 0
|
|
436
443
|
|