# f-22: Add `--changed` Flag to `publish` Command

- **Milestone:** M1
- **Complexity:** Low
- **Depends On:** None

## 1. Problem Statement

When using `kley publish --push` in a watch/loop scenario (e.g. file watcher triggers publish on every save), the command runs even if the package content hasn't actually changed. This causes unnecessary file copies, registry writes, and downstream updates for all consumer projects.

## 2. Proposed Solution

Add a `--changed` flag to `kley publish` (and by extension `kley publish --push`). When this flag is present, kley will compare the current package content against the version already in the store before proceeding.

### Logic

1. **Before copying files to the store**, compute a hash (or content signature) of the current package source files — the same set of files that `publish` would copy (respecting `.kleyignore`, `.npmignore`, `files` field, etc.).
2. **Compare** this signature with the one stored from the previous publish of this package.
3. **If identical**: skip the publish entirely. Print a brief message (e.g. "No changes detected. Skipping publish.") and exit with success.
4. **If different**: proceed with the normal publish flow, then save the new signature.

### Signature Storage

Store the signature in the global registry alongside package metadata:

```json
{
  "packages": {
    "my-lib": {
      "version": "1.2.0",
      "contentHash": "a1b2c3d4...",
      "lastUpdated": "2026-05-02T10:00:00Z",
      "installations": [...]
    }
  }
}
```

### Hash Algorithm

Use a fast, deterministic hash of file contents. Walk the same file set as `publish`, sort files by relative path, concatenate contents, and compute a SHA-256 (or similar) digest. Only file **contents** matter — timestamps and metadata are ignored.

## 3. Usage Examples

```bash
# Manual: only publish if something changed
kley publish --changed

# Watch scenario: safe to call on every file change
kley publish --push --changed

# With --sig (if implemented): append hash to version
kley publish --changed --sig
```

## 4. Acceptance Criteria

- `kley publish --changed` computes a content hash of files that would be published.
- If the hash matches the previously stored hash, publish is skipped and a message is shown.
- If the hash differs, normal publish proceeds and the new hash is saved to the registry.
- `kley publish` (without `--changed`) always publishes, regardless of changes — backward compatible.
- The hash computation respects the same file filtering rules as `publish` (`.kleyignore`, `files` field, etc.).
- Exit code is `0` in both cases (skip or publish) — both are successful outcomes.
