Skip to content

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.

Terminal window
popii upgrade check --from 0.7.6
popii upgrade plan --from 0.7.6
popii upgrade apply --dry-run --from 0.7.6
popii upgrade apply --from 0.7.6
bun install
popii upgrade verify --from 0.7.6

check 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.

  1. Confirm 0.7.6 works. Save the current command list and plugin inventory.
  2. Commit source and lockfiles. The assistant backup is extra protection, not source control.
  3. Stop all bot processes. Do not migrate SQLite while another process writes it.
  4. Back up persistence independently. Copy SQLite consistently or create a MongoDB backup.
  5. Inventory custom code. Record custom plugins, direct database access, internal imports, and runtime loading.
  6. Prepare Discord OAuth. Web v2 needs a callback matching its final public URL.
  7. Rehearse. Complete the migration and smoke tests against copied data.
Popii 0.7Popii 1.0Notes
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 listpopii plugin listInstalled plugins
popii migrate uppopii db migrateCurrent migration plan
popii dashboardpopii web checkWeb starts with the bot
popii install user/repopopii 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.

{
"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.

import { defineConfig } from "popii-framework";
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.

webPlugin({
dashboardPassword: process.env.DASHBOARD_PASSWORD,
dashboardPath: "/dashboard",
templatePath: "./templates",
viewsDir: "./views",
widgets: [],
apiKeys: true,
mongoUri: process.env.MONGODB_URI,
})

Generate the required key once:

Terminal window
popii secret generate web

Store 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/callback

It must exactly match the Discord developer portal registration.

Remove these completely:

  • reloadPlugin() / popii-reload
  • sandboxPlugin() / popii-sandbox
  • pluginManagerPlugin() / 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.

  • Library code does not call process.exit() or own global signal handlers.
  • Executions expose pop.execution and pop.signal, use bounded timeouts, and emit correlated metrics.
  • loadPlugin, unloadPlugin, and reloadPlugin are 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.

On the first Web v2 migration Popii:

  1. Creates <database>.pre-popii-1.0.bak.
  2. Applies committed schema changes transactionally.
  3. Migrates recognized guild configurations.
  4. Preserves unrelated plugin tables.
  5. Drops legacy Web sessions and API keys.
  6. 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 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.

  1. Stop the 1.0 process.
  2. Preserve redacted logs and the upgrade report.
  3. Restore source from Git or .popii-upgrade/<timestamp>/.
  4. Restore the independent database backup.
  5. Restore the old lockfile and exact 0.7 dependencies.
  6. Start 0.7 and verify commands, tasks, and persistence.

Do not point 0.7 at a partially migrated 1.0 database.

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/ready

Browser terminal, database explorer, API keys, filesystem editing, raw cache deletion, runtime plugin installation/reload, and arbitrary diagnostics are removed without compatibility aliases.

  • 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/ready succeeds 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.

Reports link to these stable codes.

No known legacy pattern was found. This does not certify custom plugin or business-logic compatibility.

package.json is missing. Run the assistant at the project root.

No popii-framework dependency exists. Identify the workspace/package arrangement manually.

The dependency is not 1.0. Apply can change an existing dependency range to ^1.0.0.

A package script uses a legacy CLI command. Apply replaces only tokens at shell-command boundaries.

package.json is invalid. Repair JSON before mutation.

Source references a retired plugin. Apply removes recognized named imports and direct calls in array literals with the TypeScript AST.

A removed Web option exists. Manual review is required because OAuth, proxy, storage, and URL choices are security-sensitive.

Source calls a removed runtime loading API. Replace it with configuration and supervised restart.

Source imports a Popii internal path. Select a documented public entry point.

No conventional popii.config.ts was found. Locate or move the configuration before applying.

popii.db exists. Back it up independently and identify whether it contains plugin data, legacy Web data, or both.

The current environment lacks POPII_WEB_ENCRYPTION_KEY. This is informational if Web is disabled; otherwise generate one.

Do not rename it blindly. Build Web v2 configuration, configure OAuth, generate the encryption key, and review proxy trust.

Two enabled definitions own the same command. Remove one, disable overlap if supported, or rename the custom command before popii sync.

Confirm startup migrations ran against the same Web database path. Check durable volume mounting and popii db status; do not create production tables manually.

Check publicUrl, Discord redirect registration, TLS/proxy headers, secure cookies, and system time. Never disable state or origin validation.

That is expected. The assistant refuses guesses that could weaken security or change custom behavior. Resolve every finding and rerun upgrade check.

Terminal window
bun install --frozen-lockfile
popii upgrade verify --from 0.7.6
popii doctor
bun run typecheck
bun test
popii db status
popii sync

Start 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.