praxisjs
Changelog for praxisjs — maintenance CLI for existing projects.
praxisjs
1.2.4
praxisjs upgrade checks Node.js and npm before installing. Instead of reacting to one npm error, it compares the toolchain with two minimums: Node.js ^20.19.0 || >=22.12.0 (Vite 8's range) and npm 11.6.0 (the first release without the peer resolution crash). An older Node.js is reported with a link to nodejs.org. In an npm project, an older npm makes upgrade ask to update it before the install runs, to the newest npm release the running Node.js supports: 1.2.3 offered npm@latest, which now needs Node.js 22.22 or later and doesn't run on Node.js 20. Outside a terminal it prints the command. When the install fails, the Install failed note says which of the two to update first.
1.2.3
praxisjs upgrade offers to update npm when it crashes. npm releases before 11.6.0 can crash with Cannot read properties of null (reading 'edgesOut') while resolving peer dependencies (vite 8's optional peers reach the vitest packages, which pin each other at exact versions). When the install fails that way, upgrade says which npm you have, asks to update it to the latest version and installs again. Outside a terminal it prints npm install --global npm@latest instead.
The install and the npm update now run without blocking the CLI, so their spinners keep moving instead of looking frozen until the package manager finishes.
1.2.2
praxisjs upgrade no longer holds Morphos back after an unfinished upgrade. In a project where an earlier upgrade rewrote package.json but its install failed, the peer checks read the old copy left in node_modules: a stale @morphos/core 0.1.3 held back every Morphos package that needs 0.1.6 and showed false "Already incompatible" notes. An installed copy outside the range package.json declares is now ignored, since the install replaces it. Before an npm install, upgrade also deletes node_modules/.package-lock.json, npm's hidden lockfile, which still listed the package folders it removes.
1.2.1
praxisjs upgrade installs reliably. With npm it first drops the @praxisjs/*, @morphos/* and kosmesis entries (and their folders) from package-lock.json: their old releases pinned exact versions of each other, so npm install failed with ERESOLVE or crashed in its peer resolution and left the project unable to run. Every other dependency keeps its locked version. On Windows the package manager now runs through a shell (it is a .cmd script, so the install failed every time), and a failed install shows the end of the package manager's output.
praxisjs upgrade repairs an upgrade that did not finish. When package.json is already up to date but the versions in node_modules don't match it, upgrade lists them under "Installed versions out of date" and installs again, instead of reporting nothing to upgrade. Projects an older upgrade left broken are fixed by running npx praxisjs@latest upgrade again.
1.2.0
New praxisjs add kosmesis. Sets up Kosmesis UI components in a project you already have, Tauri apps included. It checks that the project uses PraxisJS, reports what it found (template, Tauri, package manager, AI integration), installs the dependencies when node_modules is missing, runs kosmesis init through your package manager (kosmesis@^0.6.0) and adds the components you ask for. In a terminal without flags, kosmesis init asks its own questions; --style-system, --components, --yes and the kosmesis init flags run it without prompts. When the setup fails, it prints the commands to finish by hand and exits with code 1. See add kosmesis.
Prompts to start with your agent. ai add ends with a prompt to paste into Claude Code or Codex that maps the project into its memory with the praxisjs-memory-bootstrap skill and confirms the folder structure and conventions with you. ai sync prints it when it adds the MCP server to a project that didn't have it, and add kosmesis when an AI integration is installed. The prompts are also in the Quick Start.
The skills ask before mapping the project. When the project memory is not set up, the agent no longer starts a full analysis on its own at session start. It runs praxisjs_inspect_project first, then asks, in the same message as the .praxisjs-ai.json questions, whether the project is still the empty scaffold or should be mapped now (scaffold / map), with a suggested answer. The answer is saved as memory in .praxisjs-ai.json, so it is asked once. scaffold sets the memory up with praxisjs_memory_init only (the folder structure and UI library conventions); map runs the praxisjs-memory-bootstrap skill, which otherwise runs only when you ask for it, for example with the map prompt. Claude Code and Codex skills say the same. See First session.
The AI skills list the new Performance pages (benchmarks, why PraxisJS is fast, writing fast PraxisJS code), and the performance skill points agents to them.
1.1.0
ai add now sets up the MCP server where Claude Code reads it. It used to write the server into .claude/settings.json, which Claude Code ignores for MCP servers, so the skills' docs tools never started. It now adds it to .mcp.json and approves it in .claude/settings.json (enabledMcpjsonServers), and for Codex it adds [mcp_servers.praxisjs] to the project's .codex/config.toml. Existing configs are merged instead of overwritten, a leftover mcpServers.praxisjs in .claude/settings.json is removed, and a config that isn't valid JSON is left alone with a warning. ai remove removes only the PraxisJS skills and server and keeps your other settings. doctor reports a missing MCP server configuration and missing skills. See ai add.
praxisjs ai sync updates existing AI setups. It brings every installed integration up to this version in place: new skills are added, unedited old files are replaced, files no longer shipped are removed, and the MCP configuration is rewritten. Files you edited are kept unless you confirm the diff (never without a terminal). Installs from earlier releases are recognized by the hashes of the files they shipped, and .praxisjs-ai.lock.json records what was installed from now on. --dry-run previews; running it twice changes nothing. ai add on an installed integration runs the same update, doctor reports an outdated setup, and upgrade offers to sync it. See ai sync.
Stricter, shorter AI guidance. The Claude Code and Codex skills (now generated from one text, so they never drift) open with ten rules: look every API up through the MCP server, connect the server first, check for duplicates before writing anything reusable, build UI from Morphos and Kosmesis first, extend PraxisJS with its own APIs (decorator builders in the setup form, Composable, store plugins, devtools plugins), never use accessor, keep the project's folder structure and reorganize misplaced code, use the project memory only through the MCP server, validate every changed file, no workarounds.
Eleven more skills, installed with the main one: praxisjs-component, praxisjs-decorator, praxisjs-composable, praxisjs-store, praxisjs-testing, praxisjs-performance, praxisjs-upgrade, praxisjs-memory, praxisjs-memory-bootstrap (a full first analysis of the project into the memory, as parallel passes), praxisjs-ui (Morphos primitives and Kosmesis components first: find, add with the kosmesis CLI, wrap, update) and praxisjs-ai-setup (migrate an older project's AI setup), sharing references on the MCP server, the project memory, the project structure (by kind, or feature slices as an example layout) and the extension APIs. See AI skills.
upgrade also upgrades Morphos and Kosmesis. @morphos/* packages and the kosmesis CLI are bumped with the same rules as @praxisjs/*, when the project already lists them; nothing is added. Before writing package.json, upgrade reads the peer dependencies of every release it picks and holds back an upgrade that would break one, for example a Morphos release that needs a newer @praxisjs/core than the project gets. Held back @praxisjs/* packages stay together, since they depend on each other at exact versions. Peer conflicts the project already had are listed without changing anything. The output is grouped into PraxisJS, Morphos and Kosmesis. In a Kosmesis project (a kosmesis dependency or a Kosmesis components.json), upgrade then runs the installed kosmesis outdated (0.5.0 or later) or prints the command to run, since copied components are not npm packages. See upgrade.
doctor checks that @praxisjs/* versions work together. It reads the installed versions (or the declared ranges when nothing is installed) and flags @praxisjs/vite-plugin 4.1+ or @praxisjs/jsx 0.8+ next to a @praxisjs/runtime older than 0.8 (or no runtime dependency at all, for the plugin, whose compiled templates import from it), and @praxisjs/decorators 1.8+ next to a @praxisjs/core older than 2.3. See doctor.
upgrade fixes:
- A dependency ahead of the
latesttag, such as a prerelease, was rewritten down tolatest.upgradenow only moves a dependency forward. - A malformed
package.jsoncrashed with a stack trace. It is now reported andupgradeexits with code1. bun.lock(Bun's text lockfile) is detected, not onlybun.lockb.
upgrade also looks every package up in parallel, once per name, and honors npm_config_registry like create-praxisjs does.
AI skills (Claude Code and Codex) describe this release's APIs: For and Index lists with a pattern in the core section, @Selector, createTransition() for list transitions, the Vite plugin's compiled templates and keyed-list rewrite, the upload composables, the devtools debugging options (@Debug({ log, break }), @Trace({ slow }), the profiler and Performance tab), and the Storybook preset's automatic preview setup. The docs slug table gained essentials/lists and composables/upload, and the install examples pass dev: false for runtime packages.
1.0.2
The Claude Code and Codex skill instructions were refreshed against the current framework surface.
Two corrections matter most. StatefulComponent, StatelessComponent, and Composable are imported from @praxisjs/core, not @praxisjs/runtime — the skills previously taught the wrong path. And StatelessComponent receives its props as a generic type parameter read through this.props; @Prop, @State, @Watch, @Emit, and @Slot only work on StatefulComponent, where the old skill example used @Prop() on a stateless component. The import { signal, computed, effect, batch } from '@praxisjs/core' example was dropped entirely: those primitives are exported from @praxisjs/core/internal and are not application API — application code uses @State, @Computed, @Resource, and @Persisted instead.
Both skills gained a Check for a native path first rule. Before implementing anything it isn't certain about, the assistant now has to search the docs for an existing PraxisJS decorator, composable, or package export instead of hand-rolling it — and check for a first-party equivalent before reaching for a third-party dependency. The rule ships with a lookup table mapping roughly twenty-five commonly hand-written utilities to the API that already covers them: debounce timers to @Debounce, manual loading/error flags to @Resource, localStorage sync to @Persisted, undo stacks to @History, resize and intersection listeners to the DOM composables, requestAnimationFrame loops to @Tween/@Spring, singleton state objects to @Storable, retry loops to @Retry, list virtualization to VirtualList, and so on. When nothing native fits, the assistant records what it built and why in the project memory file. The same working agreement was added to the bundled CLAUDE.md and AGENTS.md templates.
Both skills now carry a per-package API map — decorators grouped by category, the public exports of router, store, DI, content, CSS, concurrent, composables, and the tooling entry points — plus the complete docs slug table (css/*, tooling/ssg, tooling/storybook, tooling/cli, tooling/devtools-plugins, ecosystem/ui, guide/*, internal/*), the blog scaffolding template, render() and lifecycle-hook basics, the reference-vs-mutation rule for signals, a warning about the Lazy name collision between @praxisjs/decorators and @praxisjs/router, and all four MCP tools including praxisjs_full_docs.
The bundled CLAUDE.md / AGENTS.md templates gained a content/blog variant covering @praxisjs/content and @praxisjs/ssg prerendering, and the project-config reference now explains Stylesheet vs. ReactiveStylesheet and shows a store-based i18n pattern.
1.0.1
praxisjs doctor now flags useDefineForClassFields: false instead of true in tsconfig.json, matching the Vite 8 / oxc requirement described in the @praxisjs/vite-plugin changelog. Projects still on the old Vite 7 setup with false will need to flip this once they upgrade.
Bumped the tsdown build dependency from 0.20.3 to 0.22.4 — the older version's typescript peer range (^5.0.0) didn't include this repo's [email protected], so pnpm install reported an unmet peer dependency. No change to the published output.
1.0.0
Breaking: the add command is renamed to ai add — run praxisjs ai add instead of praxisjs add. This makes room for future praxisjs ai <subcommand> commands.
Three new commands:
praxisjs ai remove— removes an AI integration: deletes the skill directory and, for Claude Code,.claude/settings.json. LeavesCLAUDE.md/AGENTS.mdand.praxisjs-ai.jsonuntouched.praxisjs doctor— diagnoses common project issues: missing@praxisjs/*dependencies, tsconfig options required by PraxisJS (jsxImportSource,jsx,useDefineForClassFields), and whether an installed AI integration (Claude Code or Codex) is fully initialized — skill files, MCP config/AGENTS.md, the memory file (CLAUDE.md/AGENTS.md), and.praxisjs-ai.jsonall present.praxisjs upgrade— updates every@praxisjs/*dependency inpackage.jsonto its latest published version and reinstalls with the detected package manager.
The Claude Code and Codex skill instructions were also rewritten to match the current framework: the full docs slug list (@praxisjs/css, @praxisjs/head, @praxisjs/content, DevTools decorators, list composables), the renamed router/store APIs (@Router/@Route, @Storable/@Store), the praxisjs_get_install_command MCP tool for dependency installs, and pointers to praxisjs doctor / praxisjs upgrade for existing-project maintenance.
0.1.0
Initial release. Provides praxisjs add — installs an AI integration (Claude Code or Codex skill) into an existing project. This is the same add command previously shipped in create-praxisjs.