Upgrade to Popii 1.0 — Cakemix
Popii 1.0 Cakemix is a breaking production release. This guide uses 0.7.6 as the authoritative legacy baseline. Upgrade a committed project or disposable copy first; never rehearse against your only production database.
Upgrade assistant
Section titled “Upgrade assistant”popii upgrade check --from 0.7.6popii upgrade plan --from 0.7.6popii upgrade apply --dry-run --from 0.7.6popii upgrade apply --from 0.7.6bun installpopii upgrade verify --from 0.7.6check is read-only. plan additionally writes popii-upgrade-report.md. apply creates .popii-upgrade/<timestamp>/ before atomic file changes. verify repeats discovery and runs the project’s typecheck script when present.
Use root --json for automation. upgrade apply --yes skips confirmation, not backups. Reports include finding descriptions and file paths, never environment values or secret contents.
Before upgrading
Section titled “Before upgrading”- Confirm 0.7.6 works. Save the current command list and plugin inventory.
- Commit source and lockfiles. The assistant backup is extra protection, not source control.
- Stop all bot processes. Do not migrate SQLite while another process writes it.
- Back up persistence independently. Copy SQLite consistently or create a MongoDB backup.
- Inventory custom code. Record custom plugins, direct database access, internal imports, and runtime loading.
- Prepare Discord OAuth. Web v2 needs a callback matching its final public URL.
- Rehearse. Complete the migration and smoke tests against copied data.
CLI mapping
Section titled “CLI mapping”| Popii 0.7 | Popii 1.0 | Notes |
|---|---|---|
popii g <type> <name> | popii generate <type> <name> | Full spelling |
popii add <package> | popii plugin add <package> | npm packages only |
popii remove <package> | popii plugin remove <package> | Transactional config edit |
popii search <query> | popii plugin search <query> | npm catalog |
popii list | popii plugin list | Installed plugins |
popii migrate up | popii db migrate | Current migration plan |
popii dashboard | popii web check | Web starts with the bot |
popii install user/repo | popii plugin add <npm-package> | Raw/GitHub installation removed |
Legacy invocations exit nonzero with guidance. Update deployment scripts, CI, containers, process managers, and documentation—not only shell usage.
Package and imports
Section titled “Package and imports”{ "dependencies": { "popii-framework": "^1.0.0" }}Use public entry points:
import { defineConfig } from "popii-framework/config";import { command } from "popii-framework/commands";import { sqlitePlugin, economyPlugin } from "popii-framework/plugins";import { createMockPop } from "popii-framework/testing";Imports from popii-framework/src/*, popii-framework/dist/*, or internal Web modules are unsupported. The generated reference index and API Reference navigation define the public boundary.
Configuration
Section titled “Configuration”Minimal bot
Section titled “Minimal bot”import { defineConfig } from "popii-framework";export default defineConfig({ token: process.env.DISCORD_TOKEN, plugins: [] });import { defineConfig } from "popii-framework/config";export default defineConfig({ token: process.env.DISCORD_TOKEN!, plugins: [] });Run popii doctor after changing configuration. Unknown built-in options now fail construction instead of being ignored.
Web plugin
Section titled “Web plugin”webPlugin({ dashboardPassword: process.env.DASHBOARD_PASSWORD, dashboardPath: "/dashboard", templatePath: "./templates", viewsDir: "./views", widgets: [], apiKeys: true, mongoUri: process.env.MONGODB_URI,})webPlugin({ hostname: "127.0.0.1", port: 3000, publicUrl: "https://bot.example.com", oauth: { clientId: process.env.DISCORD_CLIENT_ID!, clientSecret: process.env.DISCORD_CLIENT_SECRET!, }, database: { path: "./data/popii-web.db", migrateOnStartup: true }, proxy: { trustedHops: 1 }, branding: { name: "My Bot", surfaceStyle: "soft" },})Generate the required key once:
popii secret generate webStore it as POPII_WEB_ENCRYPTION_KEY. It must be base64 for exactly 32 bytes. Do not reuse a Discord or OAuth secret. Set proxy.trustedHops to the exact trusted reverse-proxy count; use zero for direct connections.
The default OAuth callback is:
https://bot.example.com/auth/discord/callbackIt must exactly match the Discord developer portal registration.
Plugin migration
Section titled “Plugin migration”Remove these completely:
reloadPlugin()/popii-reloadsandboxPlugin()/popii-sandboxpluginManagerPlugin()/popii-plugin-manager
There is no compatibility mode. Change configuration through source/CLI and activate it with a supervised restart. Browser code execution and runtime installation remain removed.
Built-ins now validate dependencies, conflicts, options, command names, and cleanup:
- Select exactly one plugin persistence provider: SQLite or Mongoose.
- Web sessions/security metadata remain in Web’s private SQLite database even when plugin data uses MongoDB.
- Install optional peers for Canvas, Mongoose, and Voice explicitly.
- Resolve command collisions before sync.
- Review the complete built-in reference for options and intents.
Custom plugins should validate options with Zod, declare dependencies/capabilities, release resources in cleanup, and contribute dashboard descriptors rather than arbitrary Hono routes or JSX.
Runtime changes
Section titled “Runtime changes”- Library code does not call
process.exit()or own global signal handlers. - Executions expose
pop.executionandpop.signal, use bounded timeouts, and emit correlated metrics. loadPlugin,unloadPlugin, andreloadPluginare removed from public client APIs.- Commands, events, middleware, snaps, components, and tasks remain, using documented entry points.
- Text commands remain supported; enable Discord Message Content Intent and configure prefixes.
- Long work such as media extraction must not remain inside a short command execution deadline.
Data migration
Section titled “Data migration”Web SQLite
Section titled “Web SQLite”On the first Web v2 migration Popii:
- Creates
<database>.pre-popii-1.0.bak. - Applies committed schema changes transactionally.
- Migrates recognized guild configurations.
- Preserves unrelated plugin tables.
- Drops legacy Web sessions and API keys.
- Restores the original database when migration fails.
Users must sign in again. API keys do not migrate because 1.0 has no public/browser API-key system.
Use separate database paths where practical:
plugins: [ sqlitePlugin({ filename: "./data/popii-plugin.db" }), webPlugin({ // publicUrl and oauth omitted here database: { path: "./data/popii-web.db" }, }),]Both files require durable writable storage and external backups. Ephemeral container storage is unsafe.
MongoDB
Section titled “MongoDB”MongoDB remains available for plugin workflow data through mongoosePlugin(). It is not used for Web sessions, OAuth state, audit metadata, or dashboard role grants. Back up MongoDB, apply each plugin’s schema migration, and test pagination/version conflicts before production.
Rollback
Section titled “Rollback”- Stop the 1.0 process.
- Preserve redacted logs and the upgrade report.
- Restore source from Git or
.popii-upgrade/<timestamp>/. - Restore the independent database backup.
- Restore the old lockfile and exact 0.7 dependencies.
- Start 0.7 and verify commands, tasks, and persistence.
Do not point 0.7 at a partially migrated 1.0 database.
Dashboard changes
Section titled “Dashboard changes”Password authentication becomes Discord OAuth with separate member, guild-manager, delegated-role, and owner access. Authorization rechecks current bot presence and Discord permissions before mutations.
These health routes stay stable:
/health/live/health/readyBrowser terminal, database explorer, API keys, filesystem editing, raw cache deletion, runtime plugin installation/reload, and arbitrary diagnostics are removed without compatibility aliases.
Production checklist
Section titled “Production checklist”- Bun satisfies the documented version requirement.
- Tokens, OAuth credentials, and encryption keys use the deployment secret store.
- Discord redirect URI exactly matches the callback.
- SQLite paths use durable writable storage.
- TLS and trusted proxy hops are correct.
/health/readysucceeds after Discord and migrations are ready.- Logs contain request IDs without cookies, OAuth codes, tokens, or environment values.
- Restart preserves plugin and Web data.
- Upgrade verification, doctor, tests, database status, and command sync pass.
Finding reference
Section titled “Finding reference”Reports link to these stable codes.
UPG000
Section titled “UPG000”No known legacy pattern was found. This does not certify custom plugin or business-logic compatibility.
UPG001
Section titled “UPG001”package.json is missing. Run the assistant at the project root.
UPG002
Section titled “UPG002”No popii-framework dependency exists. Identify the workspace/package arrangement manually.
UPG003
Section titled “UPG003”The dependency is not 1.0. Apply can change an existing dependency range to ^1.0.0.
UPG004
Section titled “UPG004”A package script uses a legacy CLI command. Apply replaces only tokens at shell-command boundaries.
UPG005
Section titled “UPG005”package.json is invalid. Repair JSON before mutation.
UPG006
Section titled “UPG006”Source references a retired plugin. Apply removes recognized named imports and direct calls in array literals with the TypeScript AST.
UPG007
Section titled “UPG007”A removed Web option exists. Manual review is required because OAuth, proxy, storage, and URL choices are security-sensitive.
UPG008
Section titled “UPG008”Source calls a removed runtime loading API. Replace it with configuration and supervised restart.
UPG009
Section titled “UPG009”Source imports a Popii internal path. Select a documented public entry point.
UPG010
Section titled “UPG010”No conventional popii.config.ts was found. Locate or move the configuration before applying.
UPG011
Section titled “UPG011”popii.db exists. Back it up independently and identify whether it contains plugin data, legacy Web data, or both.
UPG012
Section titled “UPG012”The current environment lacks POPII_WEB_ENCRYPTION_KEY. This is informational if Web is disabled; otherwise generate one.
Troubleshooting
Section titled “Troubleshooting”Removed Web option
Section titled “Removed Web option”Do not rename it blindly. Build Web v2 configuration, configure OAuth, generate the encryption key, and review proxy trust.
Plugin command collision
Section titled “Plugin command collision”Two enabled definitions own the same command. Remove one, disable overlap if supported, or rename the custom command before popii sync.
no such table after upgrade
Section titled “no such table after upgrade”Confirm startup migrations ran against the same Web database path. Check durable volume mounting and popii db status; do not create production tables manually.
OAuth state or redirect failure
Section titled “OAuth state or redirect failure”Check publicUrl, Discord redirect registration, TLS/proxy headers, secure cookies, and system time. Never disable state or origin validation.
Manual findings remain
Section titled “Manual findings remain”That is expected. The assistant refuses guesses that could weaken security or change custom behavior. Resolve every finding and rerun upgrade check.
Final rehearsal
Section titled “Final rehearsal”bun install --frozen-lockfilepopii upgrade verify --from 0.7.6popii doctorbun run typecheckbun testpopii db statuspopii syncStart copied production data and verify login, guild isolation, one privileged audited mutation, tasks, each enabled plugin’s primary workflow, shutdown cleanup, restart persistence, liveness, and readiness before moving traffic.