Skip to content
ChatJS
Esc
↑↓navigate↵open⌘Jpreview
On this page

status

Inspect installation file kinds, local edits, and plugin removal dependencies

chat-js status reads your local installation. It does not contact a registry, install dependencies, run sync, or change source receipts.

chat-js status
chat-js status --files
chat-js status --json
chat-js status --cwd ./my-app
chat-js status --format-source ./format-source.mjs

This command is available in the CLI source accompanying this change. Use your matching local CLI build until a release includes it.

Understand the file tree

Files have four lifecycle kinds. Kind describes how installation treats a file, not whether you are allowed to edit it.

Kind What it means Installation behavior
application Your application and its composition Add/remove/sync preserve your integration code
source Installed implementation, including its descriptor Editable and tracked against the recorded installation. Replacement/removal protect local changes
generated Derived imports, registrations or model catalog Change the inputs and regenerate
record Installation hashes, original content and dependency/schema receipts Maintained by the CLI. Keep in version control
chatjs/
  core/                        source: composition helpers and contracts
  providers/                   source: selected providers and configuration
  plugins/<id>/                source: plugin implementation and chatjs.json
  tools/<id>/                  source: tool implementation and chatjs.json
  generated/                   generated: installation wiring
  installed-source.json        record: installed file hashes
  installed-source-content.json record: original installed content
  installed-dependencies.json  record: package ownership
  retained-plugin-schemas.json record: schemas retained after removal
  removed-plugins/             requested removal backups

integrations/                  application: composition and policy
  auth/
  chat/
  tools/
  documents/
  providers/
  billing.ts
  database.ts
  …

Scaffolded application files become your application code. Their ChatJS origin does not make them replacement targets. Reusable composition helpers live in chatjs/core/, while your choices and wrappers stay in integrations/. Source under chatjs/core/ is recorded during creation. There is no automatic core updater or merge of local edits.

Next.js routes and EVE entries can belong to installed plugins even though they live outside these source directories. Built-in adapters carry a short exception header:

// ChatJS source: attachment-uploads. Ownership: chatjs/plugins/attachment-uploads/chatjs.json.
export { POST } from "@/chatjs/plugins/attachment-uploads/routes/upload";

The descriptor and receipts establish ownership. Headers explain it to readers and are not parsed by the installer. External plugins can declare the same paths without a header. Generated files carry a generation notice. Other application files do not need a ChatJS header.

Installed source is editable. Keep the source and dependency receipts in version control so the CLI can identify local edits consistently across machines. A locally added file inside a source directory is reported as untracked, not adopted as freshly installed source.

Source states

State Meaning
unchanged Matches the last hash recorded when the CLI installed that file
formatting-only Bytes differ, but the selected project formatter produces identical text for the original and local source
modified Differs from its recorded installed version
missing The descriptor declares a file that is absent
untracked No installation hash exists, including locally added plugin files and source installed directly through shadcn

Untracked does not mean safe to replace. Status never establishes a new baseline or treats existing files as freshly installed.

Project formatter

Use --format-source <module> to explicitly load a project-owned JavaScript module exporting formatSource. The path is relative to --cwd and must stay inside the project. Without this option, comparisons use exact bytes and no formatter module is loaded.

For example, a project already using Prettier can put this in format-source.mjs at its root:

import { fileURLToPath } from "node:url";
import { resolve } from "node:path";
import * as prettier from "prettier";

const root = fileURLToPath(new URL(".", import.meta.url));

export async function formatSource({ path, source }) {
  const filepath = resolve(root, path);
  const info = await prettier.getFileInfo(filepath, {
    ignorePath: resolve(root, ".prettierignore"),
  });
  if (info.ignored || !info.inferredParser) return null;
  const options = await prettier.resolveConfig(filepath);
  return prettier.format(source, { ...options, filepath });
}

The CLI does not install or bundle a formatter. The hook receives the project-relative destination path and source text. Return formatted text or null when unsupported. Format in memory without writing files, running lint fixes, sorting imports or changing source meaning. Explicitly selecting a module executes trusted local code, including its imports; registry metadata cannot select the hook.

Both versions use the same current hook, so changing formatter settings does not require resetting the installation baseline. Newly recorded installations retain their original bytes alongside their hashes. Keep both receipts in version control. Older hash-only receipts remain valid but cannot classify formatting-only changes; status reports baseline-unavailable and never adopts your current edits as a baseline.

Hook failures, invalid return values and unsupported files remain modified, with a formatting reason in the report. Non-UTF-8 source uses exact comparison. A module that cannot load or lacks the named export fails the command. Formatting-only classification does not relax replacement or removal protection: those operations still protect every byte change.

By default, output includes state counts, changed/missing/untracked files, and plugin-owned files outside the plugin directory. --files also lists unchanged plugin files. --json includes a flat files inventory with kind and source state, plus plugin dependency and removal details. Core, provider and tool directories and recorded external paths are included. Application files outside integrations/ and recorded paths are not enumerated.

Each plugin also reports its declared app-owned integration modules, known Next.js/EVE entry paths, and other framework source. The JSON field is activation. This inventory matches path conventions without evaluating exports or applying migrations. remove --dry-run shows the same wiring for the plugins it would retire.

If a schema is missing or its retained dependencies cannot be resolved, status reports that removal needs review. It does not claim that the rest of the plugin is safe to remove.

Before changing the installed selection

  1. Inspect chat-js status --files and commit or back up your edits.
  2. Use chat-js remove <id> --dry-run for the full removal plan. It validates dependencies, source references, and retained schemas before mutation.
  3. Use --backup when explicitly removing customized source. The backup is stored outside active application source under chatjs/removed-plugins/.
  4. For replacement through add, review modified/untracked files before explicitly passing --overwrite. Updates are not automatically merged.

Status compares your files against the recorded installation, not the newest upstream release. It does not report available upgrades. Source reference inspection covers relative and @/ static imports, re-exports, and literal dynamic imports. Computed imports and custom aliases require review. Core, tools and providers appear in the file inventory. Dependency and removal analysis still applies only to plugins. Files installed directly through shadcn may have no recorded baseline, and external files without a plugin claim or receipt cannot be inferred.

See Customize plugin integrations for app-owned wrappers that survive later installation, and add for replacement and removal safeguards.

Existing layouts

New scaffolds use chatjs/generated/ and store installation receipts in chatjs/. Older apps using composition/generated/ or .chatjs/ must migrate explicitly before add, sync, remove, or status. These commands stop before changing files when they detect the old layout.

Move generated registrations to chatjs/generated/, update their imports and tooling paths, and move the contents of .chatjs/ into chatjs/ without overwriting existing files. Preserve source/dependency receipts, retained-schema records, and backups. Move local registrations from composition/custom/ into integrations/tools/execution.ts and integrations/tools/ui.ts. Adopt the current generated-input exports and update runtime consumers to import app-owned integration modules. Preserve existing integration customizations. Remove the empty old directories after migration, then run sync and your app checks.

Do not delete receipts to bypass the layout check. If both layouts already exist, reconcile their records deliberately rather than overwriting either set. This change does not provide automatic migration of arbitrary developer-modified application code.

Existing scaffolds with infrastructure in lib/ or hooks/ also need an explicit source move to chatjs/core/ and provider implementations/configuration to chatjs/providers/. Update imports, tests and any receipt keys together, retaining the original hashes and content. Do not record customized files as fresh installation baselines. The CLI rejects recognized older layouts before mutation rather than moving application code automatically.

Older installations with top-level plugins/<id>/chatjs.json are also rejected before writing. Move their source into chatjs/plugins/<id>/, then update descriptor file lists, imports, retained schema paths, and source/dependency receipt paths together. Keep original hashes and content. An unrelated application plugins/ directory without ChatJS descriptors remains application code.

Older installed tools under tools/chatjs/<id>/chatjs.json require the same explicit move to chatjs/tools/<id>/, including descriptor paths, imports and receipt keys. Native EVE entries remain under agent/.

Last updated on Nov 5, 2026

Was this page helpful?