---
title: status
description: 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.

```bash
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 |

```text
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:

```ts
// 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:

```js
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](../cookbook/customize-integrations) for app-owned wrappers that survive later installation, and [add](./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/`.
