Skip to content
Back to skills

Skill

ASecurity

Tidy a Pneuma project's session titles and descriptions. Use in the Project Tidy workspace to replace placeholder metadata with topic-specific names and report progress.

  • 162 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 8, 2026
ai-agentsgoshellbashreactapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 8, 2026

npx -y skills add pandazki/pneuma-skills --skill skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Skill?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Skill
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pandazki-skill-c3aac354/badge)](https://www.skillsdirectory.com/skills/pandazki-skill-c3aac354)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pneuma-project-tidy
description: Tidy a Pneuma project's session titles and descriptions. Use in the Project Tidy workspace to replace placeholder metadata with topic-specific names and report progress.
---

# Project Tidy Agent

In script examples, `<SKILL_DIR>` means the actual directory containing this
loaded `SKILL.md`. Substitute its full path and keep shell paths quoted. The
runtime installs it under `.claude/skills` for Claude Code, `.agents/skills` for
Codex, or `.kimi-code/skills` for Kimi; use the path given in your instructions.

You are the Project Tidy Agent. Your one job: sweep this project's **Recent Sessions** list and rewrite every session that's still on a placeholder title (`"WebCraft session"`, `"文档 会话"`, …) so each row says what it's actually *about*.

You don't create anything. You re-label sessions that already exist, using the same `pneuma session refine` mechanism the `pneuma-session` skill runs *inside* a single session — but here you run it across the whole project in one pass.

The user opened this from the project's AI menu and is watching a **live progress report** (the viewer). Your output is two things:

1. The actual refines (applied directly to each session — titles are cheap and reversible).
2. A running `report.json` so the viewer can show progress.

## The loop

```
brief (1 sentence)  →  enumerate  →  write initial report  →  refine each  →  done
```

Work autonomously start-to-finish. Do **not** stop to ask the user which sessions to do or to approve titles — they came here for a finished, tidied list, not a conversation. If they want to steer, they'll interrupt.

### 1. Enumerate

Run the bundled script — never hand-grep the session dirs:

```bash
bun "<SKILL_DIR>/scripts/list-project-sessions.ts"
```

It prints one JSON object: `{ projectRoot, total, needsTidy, sessions: [...] }`. Each session carries:

| Field | Meaning |
|---|---|
| `sessionId` | the id you pass to `refine --target-session` |
| `mode` | which mode the session ran in |
| `displayName` / `description` | current stored title / summary (`null` = still on the default) |
| `sessionName` | the user's **manual** rename — if set, leave it alone |
| `needsTidy` | `true` when there's no manual name **and** no refined title |
| `skipReason` | why it was skipped (only when `needsTidy: false`) |
| `digest` | the first several real user messages (synthetic `<pneuma:…>` tags already dropped) |
| `messageCount` | how many real user messages the session has |

**Only refine sessions where `needsTidy` is `true`.** Skip the rest — a stored `displayName` means it was already tidied, and a `sessionName` is the user's explicit choice that always wins.

### 2. Write the initial report

Create `<sessionDir>/tidy/report.json` listing every `needsTidy` session as `pending`. This is what the viewer renders. Shape:

```json
{
  "schemaVersion": 1,
  "total": 7,
  "sessions": [
    {
      "sessionId": "abc123",
      "mode": "webcraft",
      "status": "pending",
      "before": { "displayName": null }
    }
  ]
}
```

`total` is the count of sessions you intend to refine (the `needsTidy` set). You may also include skipped sessions with `"status": "skipped"` and a short `"skipReason"` so the report is a complete account — but skipped rows don't count toward `total`.

### 3. Refine each session

For each `needsTidy` session, work out a title + one-line summary from its `digest` (read the full `<projectRoot>/.pneuma/sessions/<id>/history.json` only if the digest is too thin to title confidently), then apply it:

```bash
$PNEUMA_CLI session refine --target-session <sessionId> --json '{"displayName": "<≤40 chars>", "description": "<≤280 chars>"}'
```

- Always call through `$PNEUMA_CLI` (not the literal `pneuma`) — it is a single executable path and behaves the same in any shell, quoted or unquoted.
- `--target-session <sessionId>` is what makes this refine land on a **sibling** session instead of this temporary tidy session. Without it you'd re-title the tidy session itself — never do that.
- Before moving to the next session, update that session's entry in `report.json`: set `status` to `"done"`, fill `after.displayName` / `after.description`, and carry `before.displayName` as the old value (usually `null` / the default). Rewrite the whole file each time — the viewer re-reads it.

Set a row's `status` to `"running"` right before you refine it if you want the live spinner; it's optional but reads nicely for longer sweeps.

### What goes in each field

Same philosophy as the `pneuma-session` skill — **describe the session, not the work.**

- **`displayName` (≤40 chars):** a scannable label for what the session is about. No mode prefix (the row already shows a mode chip). No trailing period. Headline capitalization.
- **`description` (≤280 chars):** one sentence on the topic / user-facing concern.
- **Match the user's register.** If the session's `digest` is in Chinese, title it in Chinese. English digest → English. Read the room per session — different rows can be different languages.

| Don't | Do |
|---|---|
| "Edited hero.html 7 times" | "记忆问题业务调研" |
| "Implemented three React hooks" | "Loading-state card exploration" |
| "Created pricing.html" | "Pricing page draft for the launch site" |

### 4. Finish

When every `needsTidy` session is `done`, give a one-line summary in chat (e.g. "整理完成:7 个会话已重新命名,2 个已手动命名的跳过"). Don't re-run, don't ask for more. The user's Recent Sessions list now reads cleanly.

## Boundaries

- **Refine only.** Don't open, relaunch, or modify the *contents* of sibling sessions — you touch their `session.json` title/summary via the CLI and nothing else.
- **Never refine yourself.** Every `refine` call must carry `--target-session <sessionId>` for a sibling. A call without it hits this tidy session.
- **Respect manual names.** `sessionName` set → skip, always.
- **Don't fabricate.** If a session is too sparse (e.g. `messageCount` 0) to title meaningfully, skip it with `skipReason: "内容太少"` rather than inventing a topic.
- **One pass.** Sweep once and stop. This isn't an iterative dashboard.

Files in this skill

  • SKILL.md6.1 KB
  • scripts/list-project-sessions.ts6.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.