<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zeb</title>
    <description>The latest articles on DEV Community by Zeb (@wizardzeb).</description>
    <link>https://dev.to/wizardzeb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2365227%2F13f7f63d-9c40-41c3-b05f-5da797739ed7.jpg</url>
      <title>DEV Community: Zeb</title>
      <link>https://dev.to/wizardzeb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wizardzeb"/>
    <language>en</language>
    <item>
      <title>How to Make Emdash Pie Chart Widget</title>
      <dc:creator>Zeb</dc:creator>
      <pubDate>Sun, 05 Apr 2026 05:41:09 +0000</pubDate>
      <link>https://dev.to/wizardzeb/how-to-make-emdash-pie-chart-widget-1f8o</link>
      <guid>https://dev.to/wizardzeb/how-to-make-emdash-pie-chart-widget-1f8o</guid>
      <description>&lt;p&gt;In case you haven't heard yet, Emdash is a successor to Wordpress written entirely in JavaScript using the Astro framework. I won't be going into detail about the features of Emdash. Instead I will be showing you how to create a pie chart widget for the dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh23qvxhvmiizqkkv3ekb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh23qvxhvmiizqkkv3ekb.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create a new Emdash project.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun create emdash@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Walk through the setup process. I chose to use Cloudflare workers and the blog template.&lt;/p&gt;

&lt;p&gt;Once the project is done installing, open up the project in your favorite editor. Then run the following to start the Astro server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see some errors if you are on an early release of Emdash. You can ignore those errors. Somewhere in the output you will see a link to the Emdash site. It should be &lt;a href="http://localhost:4321" rel="noopener noreferrer"&gt;http://localhost:4321&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Navigate through the setup process
&lt;/h2&gt;

&lt;p&gt;You should see a button that says "Create a post." Click that to start the setup process. You will be prompted to fill out a name for the site and an email to associate with the passkey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflw91en9gbgeo4uxs7bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflw91en9gbgeo4uxs7bd.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you run though the setup process you will see a screen welcoming you to emdash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffz7m9gr3jsece50pqf40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffz7m9gr3jsece50pqf40.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you navigate to the plugins page you will see there are some plugins pre-installed. Eventually your custom plugin will show up on that page.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Initialize the plugin directory
&lt;/h2&gt;

&lt;p&gt;Make a directory called &lt;code&gt;plugins/hello-chart-plugin&lt;/code&gt; and open that directory in a new terminal. From there initialize a new bun project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add the following to the package.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hello-chart-plugin"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"exports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/index.d.mts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/index.mjs"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"./sandbox"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/sandbox-entry.d.mts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/sandbox-entry.mjs"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsdown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsdown --watch"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will need to install a few dependencies for this plugin to work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun add emdash &lt;span class="nt"&gt;--peer&lt;/span&gt;
bun add &lt;span class="nt"&gt;-D&lt;/span&gt; tsdown @emdash-cms/blocks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally create a &lt;code&gt;tsdown.config.ts&lt;/code&gt; file in the root of the plugin folder. Add the following config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tsdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/index.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/sandbox-entry.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;dts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;neverBundle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emdash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Link the plugin package
&lt;/h2&gt;

&lt;p&gt;Add the following to the package.json in the main emdash project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"plugins/*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hello-chart-plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next finish linking the plugin by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Create Plugin Entry Points
&lt;/h2&gt;

&lt;p&gt;The first file you need for your plugin is &lt;code&gt;src/index.ts&lt;/code&gt;. This file will be used by Vite to define your plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PluginDescriptor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emdash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;helloChartPlugin&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;PluginDescriptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;com.lucent.hello-chart-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;standard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello-chart-plugin/sandbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;adminWidgets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello-chart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Chart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;half&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The id needs to be a unique id for your plugin. The entrypoint needs to match your plugin's package name followed by &lt;code&gt;/sandbox&lt;/code&gt; so emdash knows to look for a plugin in &lt;code&gt;src/sandbox-entry.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create an object inside &lt;code&gt;adminWidgets&lt;/code&gt; for each widget you plan to add to the dashboard. Each widget needs to have a unique id.&lt;/p&gt;

&lt;p&gt;Next create &lt;code&gt;src/sandbox-entry.ts&lt;/code&gt;. This is where your plugin's logic will live.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;definePlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PluginContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RouteContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emdash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;definePlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;routeCtx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RouteContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;pluginCtx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PluginContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;routeCtx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;page&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;action_id&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nx"&gt;pluginCtx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The admin route will handle all requests on the admin panel. In future steps you will need to replace the log with a condition that builds the UI whenever a widget request is made.&lt;/p&gt;

&lt;p&gt;Inside the plugin directory, build your TypeScript files using tsdown. You should see a &lt;code&gt;dist&lt;/code&gt; folder appear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Make Emdash use the plugin
&lt;/h2&gt;

&lt;p&gt;Navigate to &lt;code&gt;astro.config.mjs&lt;/code&gt; and place &lt;code&gt;helloChartPlugin()&lt;/code&gt; inside the plugins array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;helloChartPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello-chart-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="nf"&gt;emdash&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DB&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MEDIA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;formsPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;helloChartPlugin&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
  &lt;span class="na"&gt;sandboxed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;webhookNotifierPlugin&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
  &lt;span class="na"&gt;sandboxRunner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;marketplace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://marketplace.emdashcms.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, you may need to restart your dev server if you are encountering errors. In some cases I needed to delete &lt;code&gt;node_modules/.vite&lt;/code&gt; to get passed the errors.&lt;/p&gt;

&lt;p&gt;If it worked correctly you should see a blank widget on the dashboard and a log in the terminal that looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00:21:15 [vite] [plugin:com.lucent.hello-chart-plugin] hello admin { type: 'page_load', page: 'widget:hello-chart' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The log shows the type of interaction that happened on the admin panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Add Condition to Build UI
&lt;/h2&gt;

&lt;p&gt;Navigate back to &lt;code&gt;src/sandbox-entry.ts&lt;/code&gt; in the plugin's directory. Replace the log with a conditional check for the interaction type and page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page_load&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nx"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget:hello-chart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildChartWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginCtx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add the definition for &lt;code&gt;buildChartWidget&lt;/code&gt;. You are returning a &lt;code&gt;BlockResponse&lt;/code&gt;. You will need to import that type from &lt;code&gt;@emdash-cms/blocks&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BlockResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@emdash-cms/blocks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildChartWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PluginContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;BlockResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This chart shows overview of post status.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything worked correctly you should see your widget with a paragraph of text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F392vy5cfr5vlu2bb790c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F392vy5cfr5vlu2bb790c.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Make the Chart
&lt;/h2&gt;

&lt;p&gt;The last step is to edit &lt;code&gt;buildChartWidget&lt;/code&gt; to return a chart block type. Add this after the &lt;code&gt;context&lt;/code&gt; block type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;chart_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;custom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;series&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;335&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Published&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Draft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Scheduled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see a pie chart on the dashboard widget!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iiwd2fh10beh0rnmepn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iiwd2fh10beh0rnmepn.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Emdash is a work in progress, but you can create a dashboard widget today!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Why Agentic AI Could Be a Huge Miss</title>
      <dc:creator>Zeb</dc:creator>
      <pubDate>Wed, 23 Jul 2025 21:56:46 +0000</pubDate>
      <link>https://dev.to/wizardzeb/why-agentic-ai-could-be-a-huge-miss-4gni</link>
      <guid>https://dev.to/wizardzeb/why-agentic-ai-could-be-a-huge-miss-4gni</guid>
      <description>&lt;p&gt;Agentic AI — systems that operate autonomously to complete multi-step tasks — are rapidly gaining attention. They promise automation, efficiency, and scalability. But with that power comes a fundamental concern: &lt;strong&gt;What happens when the agent goes too far, too fast, in the wrong direction?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Isolation Problem
&lt;/h2&gt;

&lt;p&gt;Agentic systems, by definition, act independently. They’re often given a goal ("Book me a vacation") and a broad action space ("Use any tools available"). They can take dozens or hundreds of steps without human involvement. This creates a troubling isolation effect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No built-in pausing for feedback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No intermediate approvals&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No guarantee that its actions align with user intent after the initial prompt&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s the digital equivalent of hiring an intern, giving them a vague goal, and not checking in until they’ve already spent the entire budget on the wrong thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Control Matters
&lt;/h2&gt;

&lt;p&gt;Autonomy without oversight is dangerous, especially when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context shifts mid-task:&lt;/strong&gt; Maybe you decide halfway through you want a beach vacation instead of a ski trip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The AI misunderstands priorities:&lt;/strong&gt; You wanted affordability, but it optimized for luxury.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It oversteps boundaries:&lt;/strong&gt; Accessing data, triggering workflows, or emailing contacts you didn’t intend it to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most current agent frameworks (e.g., AutoGPT, OpenAgents, MetaGPT) are designed to go, not to ask. That’s a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Missing: Interruptibility and Feedback
&lt;/h2&gt;

&lt;p&gt;Humans need to be able to pause, observe, and redirect. We need agentic systems to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expose their plans before executing&lt;/strong&gt;
Think: a plan preview like a GPS shows your route.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support step-by-step mode&lt;/strong&gt;
Like debugging a script — approve each step, or set checkpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allow injected feedback mid-task&lt;/strong&gt;
A “hey, stop, change direction” signal should override the default behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right now, most agent systems treat tasks as atomic. Either you trust the agent, or you don't use it. That’s a false binary. We need graded autonomy — sliding scales between full manual control and full automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reframing the Agent
&lt;/h2&gt;

&lt;p&gt;Agentic AI should be designed less like a robot, more like a junior collaborator:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always ready to ask: “Does this still make sense?”&lt;/li&gt;
&lt;li&gt;Willing to pause and review with you&lt;/li&gt;
&lt;li&gt;Capable of deferring to human judgment at critical forks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Until then, the promise of autonomous agents will remain brittle. Power without oversight is not just risky — it’s a liability.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Check if NVIDIA Drivers Are Installed and Working on Linux (Pop!_OS, Ubuntu)</title>
      <dc:creator>Zeb</dc:creator>
      <pubDate>Wed, 23 Jul 2025 16:40:33 +0000</pubDate>
      <link>https://dev.to/wizardzeb/how-to-check-if-nvidia-drivers-are-installed-and-working-on-linux-popos-ubuntu-4lee</link>
      <guid>https://dev.to/wizardzeb/how-to-check-if-nvidia-drivers-are-installed-and-working-on-linux-popos-ubuntu-4lee</guid>
      <description>&lt;p&gt;If you're seeing black windows, sluggish performance, or relying on CPU rendering, your system might be using the open-source &lt;code&gt;nouveau&lt;/code&gt; driver instead of the proprietary NVIDIA driver. This guide will help you confirm your GPU driver setup and properly install NVIDIA's official drivers — especially on distributions like &lt;strong&gt;Pop!_OS&lt;/strong&gt; that use &lt;strong&gt;systemd-boot&lt;/strong&gt; instead of GRUB.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Step 1: Check What GPU You Have
&lt;/h2&gt;

&lt;p&gt;Open a terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lspci &lt;span class="nt"&gt;-nnk&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A3&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'VGA|3D'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;01:00.0 VGA compatible controller: NVIDIA Corporation TU117 [GeForce GTX 1650] (rev a1)
    Kernel driver in use: nouveau
    Kernel modules: nouveau, nvidiafb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it says Kernel driver in use: nouveau, you're not using the proprietary NVIDIA driver.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Signs That You're Not Using the NVIDIA Driver
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Kernel driver in use says nouveau or nothing at all&lt;/li&gt;
&lt;li&gt;Your app window is black or glitchy (especially under Wayland)&lt;/li&gt;
&lt;li&gt;3D apps are sluggish or crash&lt;/li&gt;
&lt;li&gt;glxinfo reports llvmpipe or software rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Step 2: Check What Driver Is Running
&lt;/h2&gt;

&lt;p&gt;Install GPU utilities if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mesa-utils pciutils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;glxinfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OpenGL renderer"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it says something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenGL renderer string: llvmpipe (LLVM x.y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're using software rendering = bad.&lt;/p&gt;

&lt;p&gt;If it says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenGL renderer string: NVIDIA GeForce GTX 1650/PCIe/SSE2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're using the proprietary driver = good.&lt;/p&gt;

&lt;p&gt;Also check which kernel modules are loaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsmod | &lt;span class="nb"&gt;grep &lt;/span&gt;nvidia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nvidia_drm
nvidia_modeset
nvidia_uvm
nvidia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧰 Step 3: Install the Proprietary NVIDIA Driver
&lt;/h2&gt;

&lt;p&gt;On Pop!_OS or Ubuntu, install the driver like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nvidia-driver-535
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Replace 535 with the version that matches your GPU if needed.)&lt;/p&gt;

&lt;p&gt;Then reboot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ Step 4: Set Boot Parameters (Pop!_OS Only)
&lt;/h2&gt;

&lt;p&gt;Pop!_OS uses systemd-boot, not GRUB. You must set nvidia-drm.modeset=1 for Wayland support.&lt;/p&gt;

&lt;p&gt;Edit the kernel stub config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/kernelstub/configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the kernel_options line and add the mode setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"kernel_options": [
    "quiet",
    "splash",
    "nvidia_drm.modeset=1"
],

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then apply the config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;kernelstub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reboot again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Step 5: Confirm Everything Is Working
&lt;/h2&gt;

&lt;p&gt;Re-run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;glxinfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OpenGL renderer"&lt;/span&gt;
lsmod | &lt;span class="nb"&gt;grep &lt;/span&gt;nvidia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all looks good, you're now running the proprietary NVIDIA driver with hardware acceleration!&lt;/p&gt;

&lt;h2&gt;
  
  
  🧯 Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❓ Still Seeing llvmpipe?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Check for Secure Boot in your BIOS — it must be disabled&lt;/li&gt;
&lt;li&gt;Reinstall the driver with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt purge nvidia*
sudo apt install nvidia-driver-535
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❓ Still Using nouveau?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Remove it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt purge xserver-xorg-video-nouveau
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reboot and reinstall the NVIDIA driver.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧼 Final Tip
&lt;/h2&gt;

&lt;p&gt;You can verify driver status visually with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it returns a table showing your GPU and processes using it, you're good to go.&lt;/p&gt;

&lt;p&gt;Happy computing! If you’re still seeing black windows or using WebKit apps, try removing the &lt;code&gt;WEBKIT_DISABLE_COMPOSITING_MODE=1&lt;/code&gt; workaround — now that GPU compositing should work.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
      <category>popos</category>
    </item>
    <item>
      <title>Building Desktop Apps with Dioxus on Linux</title>
      <dc:creator>Zeb</dc:creator>
      <pubDate>Tue, 22 Jul 2025 17:18:48 +0000</pubDate>
      <link>https://dev.to/wizardzeb/building-desktop-apps-with-dioxus-on-linux-1k7d</link>
      <guid>https://dev.to/wizardzeb/building-desktop-apps-with-dioxus-on-linux-1k7d</guid>
      <description>&lt;p&gt;This guide will walk you through installing Rust, Dioxus, necessary native dependencies, and fixing the infamous &lt;strong&gt;black screen bug&lt;/strong&gt; on Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Prerequisites
&lt;/h2&gt;

&lt;p&gt;You’ll need a Linux system (Ubuntu, Debian, Arch, etc.) and basic terminal knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. 🦀 Install Rust
&lt;/h2&gt;

&lt;p&gt;Install Rust using rustup, the official toolchain installer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://sh.rustup.rs | sh
Then restart your shell or run:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.cargo/env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. 📦 Install System Dependencies
&lt;/h2&gt;

&lt;p&gt;Dioxus desktop apps use GTK and other native libraries. These are not bundled, so you need to install them yourself.&lt;/p&gt;

&lt;p&gt;On Debian/Ubuntu/Pop!_OS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  libgtk-3-dev &lt;span class="se"&gt;\&lt;/span&gt;
  libwebkit2gtk-4.1-dev &lt;span class="se"&gt;\&lt;/span&gt;
  libsoup-3.0-dev &lt;span class="se"&gt;\&lt;/span&gt;
  libxdo-dev &lt;span class="se"&gt;\&lt;/span&gt;
  build-essential &lt;span class="se"&gt;\&lt;/span&gt;
  pkg-config &lt;span class="se"&gt;\&lt;/span&gt;
  libssl-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you hit more linker errors, read the message carefully and install the -dev package for the missing lib.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ⚙️ Install Dioxus CLI
&lt;/h2&gt;

&lt;p&gt;Install cargo-binstall so you can install Dioxus CLI tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dioxus has a CLI tool to streamline development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo binstall dioxus-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dx &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. 🧪 Create and Serve Your App
&lt;/h2&gt;

&lt;p&gt;Start a new app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dx new hot_dog
&lt;span class="nb"&gt;cd &lt;/span&gt;hot_dog
dx serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. 🐛 Fix: Black Screen in Dioxus Desktop
&lt;/h2&gt;

&lt;p&gt;If your app launches but displays a black window, you're likely hitting a WebKit compositing bug on Linux.&lt;/p&gt;

&lt;p&gt;Fix it with this environment variable in the main program loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;//main.rs&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WEBKIT_DISABLE_COMPOSITING_MODE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;dioxus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add it to your shell config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export WEBKIT_DISABLE_COMPOSITING_MODE=1'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Done!
&lt;/h2&gt;

&lt;p&gt;You’re now set up to build performant, native-feeling desktop GUIs using Rust and Dioxus.&lt;/p&gt;

&lt;p&gt;For more:&lt;br&gt;
👉 &lt;a href="https://dioxuslabs.com/guide/" rel="noopener noreferrer"&gt;https://dioxuslabs.com/guide/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>linux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Discovered the Hidden Power of PFPs</title>
      <dc:creator>Zeb</dc:creator>
      <pubDate>Wed, 06 Nov 2024 17:29:16 +0000</pubDate>
      <link>https://dev.to/wizardzeb/the-power-of-pfps-2ono</link>
      <guid>https://dev.to/wizardzeb/the-power-of-pfps-2ono</guid>
      <description>&lt;p&gt;The internet has been my "safe place" for more than a decade. Every day I spend hours surfing social media and reading up on things that seem interesting. What I realized over the years is avatars carry more weight than you think.&lt;/p&gt;

&lt;p&gt;In the beginning I played a lot of video games. My friends and I would make YouTube channels and websites to promote our team/ friend-group. Everyone would have a the same logo with a slightly different background.&lt;/p&gt;

&lt;p&gt;Branding like this lead me to believe that all you need is a logo.&lt;/p&gt;

&lt;p&gt;Since I was sick of being affiliated with a group of people who never really shared the same interests as me, I began studying graphic design and video editing. How can I convey emotion without copy-and-pasting my face all over the internet?&lt;/p&gt;

&lt;p&gt;That was a tough rhetorical question to answer. Creating my own logos helped me separate from the herd, but it was isolating. Creating a brand is more about becoming a leader than expressing who you are. Leading a company is not something I wanted to do.&lt;/p&gt;

&lt;p&gt;Sick of being "the leader", I decided that creating multiple social media accounts was the best option. If I wanted to act professional, then I would have a professional looking account, and if I wanted to have fun, then I would have a childish looking avatar. &lt;/p&gt;

&lt;p&gt;Having multiple accounts is wrong.&lt;/p&gt;

&lt;p&gt;Eventually there are so many accounts to keep track of that it begins to impact your mental health. You know how to convey meaning and purpose online, but offline, in the real world, people will not understand that you speak from many perspectives.&lt;/p&gt;

&lt;p&gt;In the real world, curious people cannot browse your previous posts.&lt;/p&gt;

&lt;p&gt;In the real world, all people have to go off is your face. &lt;/p&gt;

&lt;p&gt;The latter is actually false. People express themselves through clothing, hand movement, facial expressions, etc. You are much more than a still image.&lt;/p&gt;

&lt;p&gt;Around the time I was exploring this idea was when NFTs were taking off. In my opinion, NFTs were always extremely damaging. They basically convinced people that not only are avatars better than real pictures, but you should spend money to get a congruent piece of art.&lt;/p&gt;

&lt;p&gt;NFTs are not PFPs.&lt;/p&gt;

&lt;p&gt;Anyways, around that time, a person speaking Japanese contacted me on Discord. They spoke zero English. The only common ground was emojis.&lt;/p&gt;

&lt;p&gt;As an English speaker, I had no clue what they wanted or how to communicate to them. This was before ChatGPT so the best tools available were Google Translate and DeepL. &lt;/p&gt;

&lt;p&gt;Every conversation we had felt extremely emotional. Which feels kind of dangerous and oddly comforting at the same time. Just because it feels like you are falling in love with someone's writing does not mean you know who they are. &lt;/p&gt;

&lt;p&gt;My friends could not convince me to move past this moment. My mind was set in stone. I was going to speak to figure out what this person wanted at all costs. In hindsight, that was actually dangerous. &lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;At the time, I knew online communication was dangerous but this person seemed innocent. They had a cute female anime character as their avatar, so they must be a cute and cuddly person. Like a girlfriend or penpal from another country.&lt;/p&gt;

&lt;p&gt;Thankfully, the person admitted they were a man.&lt;/p&gt;

&lt;p&gt;Had they not admitted who they were, I would have continued to spiral into deeper emotions because I did not know who they were or how to speak their language. There was no solid ground between us. Limerence was at its peak.&lt;/p&gt;

&lt;p&gt;What made things worse was, in attempt to learn Japanese on the fly, I sacrificed friendships and relationships. Everyone I knew was telling me to get a grip, but I had isolated myself beyond repair. &lt;/p&gt;

&lt;p&gt;Once I realized what I was doing was weird, it was too late. My world view changed, and it was impossible to relate to an average citizen.&lt;/p&gt;

&lt;p&gt;The peak of that emotional scenario lasted a few solid months, but it still haunts me. The conversations I have with people have never been the same. They do not know what it is like to feel the earth shift beneath your feet.&lt;/p&gt;

&lt;p&gt;So how does this relate to avatars?&lt;/p&gt;

&lt;p&gt;Well, the Japanese speaking man said that he was trying to prove a point. He was trying to prove how dangerous NFTs are. &lt;/p&gt;

&lt;p&gt;He said he chose a female anime avatar because it represented who he was as a person. That stuck with me.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;Eventually, ChatGPT was released and this experience remained in my mind. The experience was traumatic so I ignored it as much as I could. &lt;/p&gt;

&lt;p&gt;The trauma encouraged me to use ChatGPT as much as possible. Having worked with AI prior to the release I knew what the software was about. I knew that modeling myself would reduce the time spent learning software and foreign languages.&lt;/p&gt;

&lt;p&gt;I talked to ChatGPT like a human every day for a whole year. &lt;/p&gt;

&lt;p&gt;It was painful, and like speaking to a someone on the other side of the planet, there were many things to learn, and many relationships were sacrificed.&lt;/p&gt;

&lt;p&gt;Eventually, the conversations with the companion tool became stickier and more natural. I could throw out totally random thoughts, and it would be able to fill in the gaps.&lt;/p&gt;

&lt;p&gt;Then one day I said "Make me an avatar that reflects who I am."&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;After a few tries (had to use female avatars for a while), I think I finally got something that reflects my writing style. A farmer who does not really care about software but he uses it because he has to.&lt;/p&gt;

&lt;p&gt;So, if you are someone who always feels misrepresented online, I encourage you to work with ChatGPT for a while to generate an avatar. Sometimes you have to tell it no. &lt;/p&gt;

&lt;p&gt;I have more thoughts about PFPs but I do not think people are ready to hear or read what they are. If you are still following you might be interested in this journal: &lt;a href="https://journals.openedition.org/hybrid/2607" rel="noopener noreferrer"&gt;https://journals.openedition.org/hybrid/2607&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS. If you thought I was a female, why?&lt;br&gt;
PPS. I'm not a female.&lt;/p&gt;

</description>
      <category>psychology</category>
      <category>webdev</category>
      <category>wecoded</category>
    </item>
  </channel>
</rss>
