Skip to main content

skill-todo

Archive completed, abandoned, and expanded tasks with CHANGE_LOG.md updates and memory harvest suggestions

Ir a la instalación

Datos de origen

Repositorio
benbrastmckie/nvim
Última actividad en el origen
24 de agosto de 2026 a las 22:21
Idioma detectado de SKILL.md
inglés
Estrellas
444
Forks
459

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
skill-todo
description
Archive completed, abandoned, and expanded tasks with CHANGE_LOG.md updates and memory harvest suggestions
allowed-tools
Bash, Edit, Read, Write, Grep, AskUserQuestion
context
direct
# Todo Skill Direct execution skill for archiving tasks, updating CHANGE_LOG.md, and suggesting memory harvesting. <context> <system_context>OpenCode task archival with changelog tracking and memory suggestions.</system_context> <task_context>Archive completed/abandoned/expanded tasks and track changes.</task_context> </context> <role>Direct execution skill for task archival operations with automated CHANGE_LOG updates and memory harvest suggestions.</role> <task>Parse arguments, scan for archivable tasks (completed, abandoned, expanded), update states, generate CHANGE_LOG entries, suggest memory harvesting from completed task artifacts.</task> <execution> <stage id="1" name="ParseArguments"> <action>Parse command arguments</action> <process> 1. Check for --dry-run flag 2. Set dry_run = true if present 3. Validate no other arguments expected </process> </stage> <stage id="1.5" name="ReconcileScan"> <action>Dry-run scan for status-stranded tasks whose artifact for the in-flight phase already exists on disk -- these are invisible to Stage 2's literal completed/abandoned match today and can never be archived until something promotes them</action> <process> This stage never auto-repairs status: `/todo` performs the system's most irreversible operations (moving directories, rewriting CHANGE_LOG.md), and a silent status promotion immediately before a silent archive move would compound two mutations with no visibility. Every call this stage makes is `--dry-run`; only a user-approved selection in Stage 9 ever calls the script live. 1. Generate a session ID via `common_session_id` (skill-todo does not source `command-gate-in.sh` and has no session ID of its own): ```bash source .claude/scripts/lib/common.sh todo_session_id="$(common_session_id)" ``` 2. Select the same four reconcilable statuses used by the `/task --sync` and `/orchestrate` triggers (positive-match against the four statuses `reconcile-task-status.sh` knows how to reconcile -- no `!=`/negation selector needed): ```bash reconcile_scan_targets=$(jq -r ' .active_projects[] | select(.status == "researching" or .status == "planning" or .status == "implementing" or .status == "partial") | .project_number ' specs/state.json) ``` 3. For each candidate, dry-run the script and collect any task whose output reports a would-promote line into `reconcile_candidates`, keeping each candidate's task number, current status, the artifact basename found, and the full dry-run output for display in Stage 8/9: ```bash reconcile_candidates=() for task_num in $reconcile_scan_targets; do recon_out=$(bash .claude/scripts/reconcile-task-status.sh "$task_num" "$todo_session_id" --dry-run 2>&1) if echo "$recon_out" | grep -q "Would promote"; then reconcile_candidates+=("$task_num") # associate $recon_out with $task_num (e.g. via an associative array) for Stage 9's # AskUserQuestion description text fi done ``` 4. If `reconcile_scan_targets` is empty, `reconcile_candidates` is `()` -- proceed straight to Stage 2. This stage is genuinely side-effect-free: `--dry-run` never writes `state.json` or any other file. </process> </stage> <stage id="2" name="ScanTasks"> <action>Scan for archivable tasks</action> <process> 1. Read specs/state.json 2. Identify tasks with status = "completed" 3. Identify tasks with status = "abandoned" 4. Identify tasks with status = "expanded" 5. Read specs/TODO.md and cross-reference (including entries marked [EXPANDED]) 6. Track counts: completed_count, abandoned_count, expanded_count **Subtasks-defer guard**: identical semantics to `commands/todo.md`'s Step 3 guard (see that file's "Prepare Archive List" section, which is the reference implementation this mirrors). Partition the tasks identified above into `archivable_tasks[]` (proceeds) and `deferred_expanded[]` (held back for a later `/todo` run) — an expanded parent is deferred while any task in its `subtasks[]` is still present in `active_projects` with a non-terminal status. Use a `case` statement for status classification (never `!=`): ```bash archivable_tasks=() deferred_expanded=() deferred_expanded_nums=() for task in "${candidate_tasks[@]}"; do status=$(echo "$task" | jq -r '.status') project_num=$(echo "$task" | jq -r '.project_number') case "$status" in expanded) # A missing, null, or empty subtasks array means nothing is blocking - archive normally. subtasks=$(echo "$task" | jq -c '.subtasks // []') subtask_count=$(echo "$subtasks" | jq 'length') if [ "$subtask_count" -eq 0 ]; then archivable_tasks+=("$task") continue fi blocking_count=0 for subtask_num in $(echo "$subtasks" | jq -r '.[]'); do subtask_status=$(jq -r --argjson n "$subtask_num" \ '.active_projects[] | select(.project_number == $n) | .status' \ specs/state.json) # An empty result means the subtask is already archived - not blocking. if [ -z "$subtask_status" ]; then continue fi case "$subtask_status" in completed|abandoned|expanded) # Terminal - not blocking. ;; *) # Any other status blocks. ((blocking_count++)) ;; esac done if [ "$blocking_count" -gt 0 ]; then deferred_expanded+=("$task") deferred_expanded_nums+=("$project_num") else archivable_tasks+=("$task") fi ;; *) # Non-expanded tasks pass through untouched. archivable_tasks+=("$task") ;; esac done ``` Track `deferred_expanded[]` and `deferred_count` (`= ${#deferred_expanded[@]}`). Stage 10 (`ArchiveTasks`) consumes `archivable_tasks[]` — never a freshly-recomputed status match — so a deferred parent's `active_projects` entry survives this run. </process> </stage> <stage id="2.5" name="TopicRevision"> <action>Optional: backfill topics on active tasks missing the topic field</action> <process> Detect active tasks without a topic: ```bash missing=$(jq -r '.active_projects[] | select(.status == "completed" | not) | select(.status == "abandoned" | not) | select(.status == "expanded" | not) | select(.topic == null or .topic == "") | "\(.project_number)|\(.project_name)"' specs/state.json) ``` If no tasks need backfill, skip this stage. For each task needing a topic, follow the topic assignment pattern from @.claude/context/patterns/topic-assignment-pattern.md (Mode A, per-task backfill). Use header "Topic Backfill ({i} of {total})". After each selection: ```bash bash .claude/scripts/manage-topics.sh set "$task_num" "$topic" ``` </process> </stage> <stage id="3" name="DetectOrphans"> <action>Detect orphaned directories and TODO.md orphans</action> <process> 1. Scan specs/ for directories not tracked in state files: ```bash for dir in specs/OC_[0-9]*_*/ specs/[0-9]*_*/; do [ -d "$dir" ] || continue basename_dir=$(basename "$dir") project_num=$(echo "$basename_dir" | sed 's/^OC_//' | cut -d_ -f1) in_active=$(jq -r --arg n "$project_num" \ '.active_projects[] | select(.project_number == ($n | tonumber)) | .project_number' \ specs/state.json 2>/dev/null) in_archive=$(jq -r --arg n "$project_num" \ '.completed_projects[] | select(.project_number == ($num | tonumber)) | .project_number' \ specs/archive/state.json 2>/dev/null) if [ -z "$in_active" ] && [ -z "$in_archive" ]; then orphaned_in_specs+=("$dir") fi done ``` 2. Scan specs/archive/ for orphaned directories: ```bash for dir in specs/archive/OC_[0-9]*_*/ specs/archive/[0-9]*_*/; do [ -d "$dir" ] || continue basename_dir=$(basename "$dir") project_num=$(echo "$basename_dir" | sed 's/^OC_//' | cut -d_ -f1) in_archive=$(jq -r --arg n "$project_num" \ '.completed_projects[] | select(.project_number == ($num | tonumber)) | .project_number' \ specs/archive/state.json 2>/dev/null) if [ -z "$in_archive" ]; then orphaned_in_archive+=("$dir") fi done ``` 3. Scan TODO.md for completed/abandoned tasks not tracked in state.json or archive: - Parse task headers (`### {N}.` or `### OC_{N}.`) and status lines (`[COMPLETED]`/`[ABANDONED]`) - Cross-reference each against active_projects and archive completed_projects - Collect as `todo_md_orphans[]` if: status is completed/abandoned, not in either state file, and has a directory in specs/ </process> </stage> <stage id="4" name="DetectMisplaced"> <action>Detect misplaced directories</action> <process> 1. Scan specs/ for directories tracked in archive state: ```bash for dir in specs/OC_[0-9]*_*/ specs/[0-9]*_*/; do [ -d "$dir" ] || continue basename_dir=$(basename "$dir") project_num=$(echo "$basename_dir" | sed 's/^OC_//' | cut -d_ -f1) in_active=$(jq -r --arg n "$project_num" \ '.active_projects[] | select(.project_number == ($num | tonumber)) | .project_number' \ specs/state.json 2>/dev/null) in_archive=$(jq -r --arg n "$project_num" \ '.completed_projects[] | select(.project_number == ($num | tonumber)) | .project_number' \ specs/archive/state.json 2>/dev/null) if [ -z "$in_active" ] && [ -n "$in_archive" ]; then misplaced_in_specs+=("$dir") fi done ``` </process> </stage> <stage id="5" name="ScanRoadmap"> <action>Scan for roadmap references</action> <process> 0. Ensure specs/ROADMAP.md exists. If the file does not exist, create it with the default template: ```markdown # Project Roadmap ## Phase 1: Current Priorities (High Priority) - [ ] (No items yet -- add roadmap items here) ## Success Metrics - (Define success metrics here) ``` 1. Partition `archivable_tasks[]` into roadmap-excluded (meta tasks, and expanded tasks — an expanded task has no `completion_summary` of its own by construction, since its subtasks carry the deliverables; do not "fix" this by requiring one) and roadmap-eligible tasks, exactly as `commands/todo.md`'s Step 3.5.1 does. 2. This stage performs no matching of its own. Invoke `roadmap-integration.sh` parse-only (no `--annotate`) against `specs/ROADMAP.md`/`specs/state.json`, capturing `roadmap_structure`, `warnings`, and `roadmap_matches` from the payload. Filter `roadmap_matches` to only the roadmap-eligible tasks from step 1 before treating any match as an annotation candidate — this filter is where meta/expanded exclusion is enforced, since the script has no `task_type` filter of its own (see the script's header "Caller contract"). 3. **Error-handling contract** (identical to `commands/todo.md`'s Step 3.5 and `commands/review.md`'s Step 2.5): a missing script, a non-zero exit, or empty output all produce the same visible warning and the same fully-defined `parseable: false` fallback — never silence. </process> </stage> <stage id="6" name="ScanMetaSuggestions"> <action>Scan meta tasks for README.md suggestions</action> <process> 1. For each archived meta task: - Check completion_data.readme_suggestions - Filter out "none" values - Track actionable suggestions by type: * Add: Insert new content * Update: Replace existing content * Remove: Delete content </process> </stage> <stage id="7" name="HarvestMemories"> <action>Collect, deduplicate, and classify memory candidates from state.json</action> <process> Note: this stage stays scoped to completed tasks and is not widened to expanded tasks — an expanded task's work product and memory candidates belong to its subtasks, which are harvested (or already were harvested) in their own right when they complete. 1. Collect candidates from state.json: - For each completed task in the archival batch: - Read `memory_candidates // []` from the task's state.json entry - Flatten into a single list, tagging each candidate with `task_number` provenance - If no candidates across all tasks, set `harvest_candidates = []` and skip to Stage 8 2. Deduplicate against existing memory-index.json:
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub