From ec6f3a6a4e3ff426e650891d95d7491dcab9f0a2 Mon Sep 17 00:00:00 2001 From: tukuaiai Date: Tue, 19 May 2026 03:16:52 +0800 Subject: [PATCH] feat: skills - import auto-tmux swarm tasks --- skills/auto-tmux/SKILL.md | 1 + skills/auto-tmux/references/automation.md | 1 + skills/auto-tmux/references/swarm-state.md | 14 ++++++++ skills/auto-tmux/scripts/README.md | 1 + .../auto-tmux/scripts/auto-tmux-smoke-test.sh | 11 +++--- skills/auto-tmux/scripts/swarm-state.sh | 36 +++++++++++++++++++ 6 files changed, 60 insertions(+), 4 deletions(-) diff --git a/skills/auto-tmux/SKILL.md b/skills/auto-tmux/SKILL.md index 7d85d6e..9a9d2cd 100644 --- a/skills/auto-tmux/SKILL.md +++ b/skills/auto-tmux/SKILL.md @@ -147,6 +147,7 @@ skills/auto-tmux/scripts/auto-tmux.sh wait -t :. --patter ```bash skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" +skills/auto-tmux/scripts/swarm-state.sh task-import --file /tmp/tasks.txt --prefix batch --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-next --owner :. skills/auto-tmux/scripts/swarm-state.sh lock-acquire --name README.md --owner :. skills/auto-tmux/scripts/swarm-state.sh lock-prune --older-than 3600 --dry-run diff --git a/skills/auto-tmux/references/automation.md b/skills/auto-tmux/references/automation.md index 7b6bff6..a95e659 100644 --- a/skills/auto-tmux/references/automation.md +++ b/skills/auto-tmux/references/automation.md @@ -189,6 +189,7 @@ skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm ```bash skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" +skills/auto-tmux/scripts/swarm-state.sh task-import --file /tmp/tasks.txt --prefix batch skills/auto-tmux/scripts/swarm-state.sh task-claim --id task-001 --owner "ai-hub:2.1" skills/auto-tmux/scripts/swarm-state.sh task-next --owner "ai-hub:2.1" ``` diff --git a/skills/auto-tmux/references/swarm-state.md b/skills/auto-tmux/references/swarm-state.md index bb2b9ec..7d2b566 100644 --- a/skills/auto-tmux/references/swarm-state.md +++ b/skills/auto-tmux/references/swarm-state.md @@ -70,6 +70,20 @@ skills/auto-tmux/scripts/swarm-state.sh status -n 20 skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" ``` +从文本文件批量导入任务: + +```bash +cat > /tmp/tasks.txt <<'EOF' +- 检查 README 链接 +- 运行 make test +- 汇总风险和下一步 +EOF + +skills/auto-tmux/scripts/swarm-state.sh task-import --file /tmp/tasks.txt --prefix batch +``` + +`task-import` 会跳过空行和 `#` 注释行,自动去掉行首 `- ` 或 `* `,并生成 `batch-001` 这类任务 ID。 + 认领任务: ```bash diff --git a/skills/auto-tmux/scripts/README.md b/skills/auto-tmux/scripts/README.md index da3c27c..d361976 100644 --- a/skills/auto-tmux/scripts/README.md +++ b/skills/auto-tmux/scripts/README.md @@ -51,6 +51,7 @@ skills/auto-tmux/scripts/swarm-watch.sh --session ai-hub --swarm-dir /tmp/ai_swa # 初始化蜂群状态并添加任务 skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" +skills/auto-tmux/scripts/swarm-state.sh task-import --file /tmp/tasks.txt --prefix batch --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-next --owner "$target" --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh lock-prune --older-than 3600 --dry-run --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-block --id task-001 --owner "$target" --reason "等待输入" --dir /tmp/ai_swarm diff --git a/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh b/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh index 489b498..ae0b4d1 100755 --- a/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh +++ b/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh @@ -16,10 +16,11 @@ RECORD_DIR="/tmp/auto-tmux-smoke-record-$$" BRIEF_DIR="/tmp/auto-tmux-smoke-brief-$$" WATCH_DIR="/tmp/auto-tmux-smoke-watch-$$" DISPATCH_PROMPT="/tmp/auto-tmux-smoke-dispatch-$$.md" +TASK_IMPORT_FILE="/tmp/auto-tmux-smoke-tasks-$$.txt" cleanup() { tmux kill-session -t "$SESSION" 2>/dev/null || true - rm -rf "$SWARM_DIR" "$SNAPSHOT_DIR" "$RECORD_DIR" "$BRIEF_DIR" "$WATCH_DIR" "$DISPATCH_PROMPT" + rm -rf "$SWARM_DIR" "$SNAPSHOT_DIR" "$RECORD_DIR" "$BRIEF_DIR" "$WATCH_DIR" "$DISPATCH_PROMPT" "$TASK_IMPORT_FILE" } trap cleanup EXIT @@ -54,6 +55,8 @@ test -s "$SNAPSHOT_DIR/topology.txt" "$SWARM_STATE" init --dir "$SWARM_DIR" >/tmp/auto-tmux-smoke-swarm-init.txt "$SWARM_STATE" task-add --dir "$SWARM_DIR" --id smoke-task --text "run smoke task" >/tmp/auto-tmux-smoke-task-add.txt +printf '%s\n' "- import task one" "- import task two" > "$TASK_IMPORT_FILE" +"$SWARM_STATE" task-import --dir "$SWARM_DIR" --file "$TASK_IMPORT_FILE" --prefix imported >/tmp/auto-tmux-smoke-task-import.txt "$SWARM_STATE" task-claim --dir "$SWARM_DIR" --id smoke-task --owner "$worker_target" "$SWARM_STATE" lock-acquire --dir "$SWARM_DIR" --name smoke-file --owner "$worker_target" >/tmp/auto-tmux-smoke-lock.txt "$SWARM_STATE" lock-release --dir "$SWARM_DIR" --name smoke-file --owner "$worker_target" >/tmp/auto-tmux-smoke-unlock.txt @@ -62,15 +65,15 @@ test -s "$SNAPSHOT_DIR/topology.txt" "$SWARM_STATE" lock-prune --dir "$SWARM_DIR" --older-than 0 >/tmp/auto-tmux-smoke-lock-prune.txt grep -q 'stale-file' /tmp/auto-tmux-smoke-lock-prune.txt "$SWARM_STATE" task-done --dir "$SWARM_DIR" --id smoke-task --owner "$worker_target" --result "ok" -"$SWARM_STATE" task-add --dir "$SWARM_DIR" --id smoke-next --text "claim next task" >/tmp/auto-tmux-smoke-task-next-add.txt "$SWARM_STATE" task-next --dir "$SWARM_DIR" --owner "$worker_target" >/tmp/auto-tmux-smoke-task-next.txt -grep -q 'smoke-next' /tmp/auto-tmux-smoke-task-next.txt -"$SWARM_STATE" task-block --dir "$SWARM_DIR" --id smoke-next --owner "$worker_target" --reason "waiting for input" +grep -q 'imported-001' /tmp/auto-tmux-smoke-task-next.txt +"$SWARM_STATE" task-block --dir "$SWARM_DIR" --id imported-001 --owner "$worker_target" --reason "waiting for input" "$SWARM_STATE" task-add --dir "$SWARM_DIR" --id smoke-fail --text "fail task" >/tmp/auto-tmux-smoke-task-fail-add.txt "$SWARM_STATE" task-fail --dir "$SWARM_DIR" --id smoke-fail --owner "$worker_target" --reason "expected failure" "$SWARM_STATE" report --dir "$SWARM_DIR" >/tmp/auto-tmux-smoke-report.txt "$SWARM_STATE" validate --dir "$SWARM_DIR" >/tmp/auto-tmux-smoke-state-validate.txt grep -q 'smoke-task' /tmp/auto-tmux-smoke-report.txt +grep -q 'imported-001' /tmp/auto-tmux-smoke-report.txt grep -q 'BLOCKED' /tmp/auto-tmux-smoke-report.txt grep -q 'FAIL' /tmp/auto-tmux-smoke-report.txt "$SWARM_BRIEF" --session "$SESSION" --swarm-dir "$SWARM_DIR" --out "$BRIEF_DIR" -n 10 >/tmp/auto-tmux-smoke-brief.txt diff --git a/skills/auto-tmux/scripts/swarm-state.sh b/skills/auto-tmux/scripts/swarm-state.sh index 4a1d418..eb12a76 100755 --- a/skills/auto-tmux/scripts/swarm-state.sh +++ b/skills/auto-tmux/scripts/swarm-state.sh @@ -18,6 +18,7 @@ Usage: swarm-state.sh log --target TARGET --status STATUS --message TEXT [--dir DIR] swarm-state.sh status [--dir DIR] swarm-state.sh task-add --text TEXT [--id ID] [--dir DIR] + swarm-state.sh task-import --file FILE [--prefix PREFIX] [--dir DIR] swarm-state.sh task-list [--dir DIR] swarm-state.sh task-next --owner TARGET [--dir DIR] swarm-state.sh task-claim --id ID --owner TARGET [--dir DIR] @@ -145,6 +146,40 @@ cmd_task_add() { printf 'task added: %s\n' "$id" } +cmd_task_import() { + local file="" prefix="" + while [[ $# -gt 0 ]]; do + case "$1" in + --dir) set_dir "${2:-}"; shift 2 ;; + --file) file="${2:-}"; shift 2 ;; + --prefix) prefix="${2:-}"; shift 2 ;; + *) die "unknown task-import option: $1" ;; + esac + done + [[ -n "$file" ]] || die "missing --file" + [[ -f "$file" ]] || die "task import file not found: $file" + ensure_init + if [[ -z "$prefix" ]]; then + prefix="task-$(date +%Y%m%d%H%M%S)" + fi + + local count=0 line text id + while IFS= read -r line || [[ -n "$line" ]]; do + text="$(printf '%s' "$line" | sed -E 's/\r$//; s/^[[:space:]]*[-*][[:space:]]+//; s/^[[:space:]]+//; s/[[:space:]]+$//')" + [[ -n "$text" ]] || continue + [[ "$text" == \#* ]] && continue + count=$((count + 1)) + id="${prefix}-$(printf '%03d' "$count")" + if awk -F '\t' -v id="$id" 'NR > 1 && $1 == id {found = 1} END {exit found ? 0 : 1}' "$TASKS_TSV"; then + die "task id already exists: $id" + fi + text="$(printf '%s' "$text" | sanitize)" + printf '%s\tTODO\t-\t%s\t-\n' "$id" "$text" >> "$TASKS_TSV" + done < "$file" + + printf 'tasks imported: %s prefix=%s\n' "$count" "$prefix" +} + cmd_task_list() { while [[ $# -gt 0 ]]; do case "$1" in @@ -477,6 +512,7 @@ main() { log) cmd_log "$@" ;; status) cmd_status "$@" ;; task-add) cmd_task_add "$@" ;; + task-import) cmd_task_import "$@" ;; task-list) cmd_task_list "$@" ;; task-next) cmd_task_next "$@" ;; task-claim) cmd_task_claim "$@" ;;