chore: initial commit — Buddy v0.1.0 (Phase A complete)

Buddy is born. First commit of a new standalone WordPress plugin —
the spiritual successor to the tamagotchi that once lived inside
A-WP-Notes v1.1.5 (gracefully retired). Rebuilt from scratch with
all the v3-discipline lessons baked in from day one.

PHASE A — pet exists
- Dashboard widget at WP Admin → Dashboard showing SVG character +
  name + mood label + four stats bars.
- Dedicated admin page at WP Admin → Buddy → My Buddy (bigger view).
- About page with side-by-side intro + plain-prose cards (Logbook
  About-page pattern carried forward).
- Settings page with name-rename form + Updates panel.
- Per-user state in user_meta key buddy_state (each WP admin gets
  their own pet, no shared state).
- Inline SVG sprite renderer with three mood tones (happy/neutral/
  sad) and three sizes (sm/md/lg). CSS keyframe animations: bobbing
  + periodic blinking. Zero image files.
- Self-hosted update checker wired up from commit 1, ported from
  Logbook v3.3.5: /releases/latest with /tags?limit=1 fallback,
  12h success cache / 1h negative cache. UI on Settings page.
- dashicons-pets admin-menu icon — literal paw-print, brand match.

ARCHITECTURE LOCKED FROM COMMIT 1
- Single-word brand name "Buddy" — no WP prefix, no future rebrand.
- Public GPL v2+ Gitea repo (ranger/a-buddy).
- Constants prefix BUDDY_*, function prefix buddy_*, text domain
  buddy. Clean naming throughout — none of Logbook's wp-notes-*
  historical-artifact baggage.
- Single H1 per admin page, no nested toggle boxes, no duplicate
  sections — Tier-1 discipline carried forward from Logbook.
- All assets local (inline SVG, plain CSS), no third-party CDN,
  no Gravatar-style external pings.

NOT IN THIS RELEASE (planned)
- Phase B — Feed/Play/Clean/Sleep interactions + cooldown timers.
- Phase C — WP-cron decay + "Buddy is hungry" dismissible notices
  (port the persistent-dismissal pattern from Logbook).
- Phase D — Multiple species (dog, dragon, sprite), per-species
  personality phrases.
- Phase E — Site-health hook: pet stats react to wp_get_site_health()
  results. The killer feature.
- Phase F — Pro tier (€2.99 lifetime) with custom skins + multi-pet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 10:23:57 +01:00
commit 48e97862a6
12 changed files with 1135 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
<?php
/**
* Buddy dashboard widget — the pet appears on the main WordPress
* Dashboard (`/wp-admin/index.php`) so the user sees it without
* navigating anywhere. This is the "Buddy exists" baseline of Phase A.
*
* The widget shows: the SVG character + the pet's name + current
* mood label + four stats bars. No interaction yet (Phase B will add
* Feed / Play / Clean / Sleep). The render also includes a "Visit
* Buddy" link that jumps to the dedicated admin page.
*/
if ( ! defined( 'ABSPATH' ) ) { exit; }
add_action( 'wp_dashboard_setup', 'buddy_register_dashboard_widget' );
function buddy_register_dashboard_widget() {
if ( ! current_user_can( 'read' ) ) { return; }
wp_add_dashboard_widget(
'buddy_dashboard_widget',
'🐾 ' . __( 'Buddy', 'buddy' ),
'buddy_render_dashboard_widget'
);
}
function buddy_render_dashboard_widget() {
$state = buddy_get_state();
$mood = buddy_overall_mood( $state );
$tone = buddy_mood_label( $mood );
?>
<div class="buddy-widget">
<div class="buddy-widget__pet">
<?php buddy_render_sprite( $state['species'], $tone['tone'], 'md' ); ?>
</div>
<div class="buddy-widget__info">
<div class="buddy-widget__name">
<?php echo esc_html( $state['name'] ); ?>
<span class="buddy-widget__mood buddy-widget__mood--<?php echo esc_attr( $tone['tone'] ); ?>">
<?php echo esc_html( $tone['label'] ); ?>
</span>
</div>
<?php buddy_render_stats_bars( $state ); ?>
<p class="buddy-widget__cta">
<a href="<?php echo esc_url( admin_url( 'admin.php?page=buddy' ) ); ?>" class="button button-small">
<?php esc_html_e( 'Visit Buddy →', 'buddy' ); ?>
</a>
</p>
</div>
</div>
<?php
}
/**
* Render the four stats as labelled progress bars. Reused by the
* dedicated admin page so they look identical wherever Buddy appears.
*/
function buddy_render_stats_bars( array $state ) {
$stats = array(
'hunger' => array( 'label' => __( 'Hunger', 'buddy' ), 'icon' => '🍎' ),
'happiness' => array( 'label' => __( 'Happiness', 'buddy' ), 'icon' => '😊' ),
'health' => array( 'label' => __( 'Health', 'buddy' ), 'icon' => '💚' ),
'energy' => array( 'label' => __( 'Energy', 'buddy' ), 'icon' => '⚡' ),
);
echo '<ul class="buddy-stats">';
foreach ( $stats as $key => $meta ) {
$val = max( 0, min( 100, (int) ( $state[ $key ] ?? 0 ) ) );
$low = $val < 30;
printf(
'<li class="buddy-stat"><span class="buddy-stat__icon" aria-hidden="true">%s</span>'
. '<span class="buddy-stat__label">%s</span>'
. '<span class="buddy-stat__bar"><span class="buddy-stat__fill%s" style="width:%d%%"></span></span>'
. '<span class="buddy-stat__num">%d</span></li>',
esc_html( $meta['icon'] ),
esc_html( $meta['label'] ),
$low ? ' buddy-stat__fill--low' : '',
$val,
$val
);
}
echo '</ul>';
}