Files
nanoclaw/.claude/skills/_shared/diagnostics.md
Koshkoshinsk f04a8955aa feat: add opt-in diagnostics via PostHog
Per-event consent diagnostics that sends anonymous install/update/skill data
to PostHog. Conflict filenames are gated against upstream. Supports --dry-run
to show exact payload before sending, and "never ask again" opt-out via state.yaml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 01:24:32 +02:00

3.0 KiB

Diagnostics (end-of-skill instructions)

Follow these steps after all other skill steps are complete.

1. Skip check

If this skill was invoked from within another skill (e.g., /add-whatsapp called during /setup), skip diagnostics entirely — the parent skill handles it. Return without doing anything below.

2. Determine event type

  • /setupsetup_complete
  • /update-nanoclawupdate_complete
  • Any other skill → skill_applied

3. Build event-specific data

Estimate error_count from the conversation (how many errors/retries occurred during the run).

For setup_complete:

{
  "channels_selected": ["whatsapp", "telegram"],
  "error_count": 0,
  "failed_step": null,
  "exit_code": null
}
  • channels_selected: which channels the user chose to install
  • failed_step: if setup failed, which step (environment / container / groups / register / mounts / service / verify)
  • exit_code: if a step failed, its exit code

For skill_applied:

{
  "skill_name": "add-telegram",
  "is_upstream_skill": true,
  "conflict_files": ["package.json", "src/index.ts"],
  "error_count": 0
}
  • skill_name: the skill that was run. Use the upstream skill name if it's an upstream skill, otherwise use "custom"
  • is_upstream_skill: true if this is a known upstream skill
  • conflict_files: filenames that had merge conflicts (the script will gate these against upstream — pass them all, the script filters)

For update_complete:

{
  "version_age_days": 45,
  "update_method": "merge",
  "conflict_files": ["package.json"],
  "breaking_changes_found": false,
  "breaking_changes_skills_run": [],
  "error_count": 0
}
  • version_age_days: estimate from the backup tag or commit date how many days old the previous version was
  • update_method: "merge" or "rebase"
  • breaking_changes_found: whether breaking changes were detected during the update
  • breaking_changes_skills_run: which skills had to be re-run to fix breaking changes

4. Dry run

Run with --dry-run to get the full payload:

npx tsx scripts/send-diagnostics.ts --event <event_type> --success --data '<json>' --dry-run

Use --failure instead of --success if the skill failed.

If the command produces no output, the user has opted out permanently — skip the rest.

5. Show the user and ask

Show the JSON output and ask:

"Would you like to send anonymous diagnostics to help improve NanoClaw? Here's exactly what would be sent:"

(show the JSON)

Yes / No / Never ask again

Use AskUserQuestion.

6. Handle response

  • Yes: Run the same command without --dry-run:

    npx tsx scripts/send-diagnostics.ts --event <event_type> --success --data '<json>'
    

    Confirm: "Diagnostics sent."

  • No: Do nothing. User will be asked again next time.

  • Never ask again: Run:

    npx tsx -e "import { setNeverAsk } from './scripts/send-diagnostics.ts'; setNeverAsk();"
    

    Confirm: "Got it — you won't be asked again."