Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Validate package manifests
working-directory: plugins
run: |
node -e 'for (const f of ["package.json","agent-sdk/package.json","memory-mcp/package.json","openclaw/package.json","claude-code/package.json","codex/package.json","cli/package.json"]) JSON.parse(require("fs").readFileSync(f,"utf8"))'
node -e 'for (const f of ["package.json","agent-sdk/package.json","memory-mcp/package.json","openclaw/package.json","claude-code/package.json","kimicode/package.json","codex/package.json","cursor/package.json","devin/package.json","dsh/package.json","cli/package.json"]) JSON.parse(require("fs").readFileSync(f,"utf8"))'
node -e 'JSON.parse(require("fs").readFileSync("everme/.codex-plugin/plugin.json","utf8"))'
node -e 'JSON.parse(require("fs").readFileSync("everme/hooks/hooks.json","utf8"))'

Expand Down Expand Up @@ -177,7 +177,12 @@ jobs:
- name: Private key check
run: |
# ci.yml is excluded so the pattern string doesn't self-match.
if grep -R --exclude-dir=.git --exclude-dir=node_modules --exclude=ci.yml -n "BEGIN .*PRIVATE KEY" .; then
# redact.go / redact_test.go are excluded for the same reason: the
# import redactor exists to *strip* credentials, so it necessarily
# carries the PEM header pattern, and its fixtures are fabricated
# placeholder bodies the test asserts get replaced.
if grep -R --exclude-dir=.git --exclude-dir=node_modules --exclude=ci.yml \
--exclude=redact.go --exclude=redact_test.go -n "BEGIN .*PRIVATE KEY" .; then
echo "::error::Private key material detected"
exit 1
fi
Expand Down
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ the open-source home for EverMe CLI and agent plugins.

### CLI

- Sync the `cli/` Go tree to the `evercli` v0.32.0 release. Earlier public
snapshots trailed the published binaries; the tree now matches what
`npm install -g @everme/cli` and the release archives ship.
- Add `evercli skill` — browse / install / manage EverMe skills.
- Restore `evercli plugin uninstall <platform>`: it removes only EverMe-owned
local state (host config entry, hooks, `everme.env`) and then disconnects the
cloud agent registered for this machine. `--keep-agent` skips the disconnect.
- Replace the flat-file import pipeline with `evercli import conversations`
(`scan` / `run`): markdown import, an idempotency ledger scoped to one
account and environment, and an `--async` two-phase bulk mode for cold-start
uploads.
- Extend `evercli plugin install` past Claude Code and OpenClaw to Codex,
Cursor, Claude Desktop, DeepSeek Harness, Devin, Hermes, Kimi Code,
opencode, Raven, and WorkBuddy.
- Force `0600` on host config files that store an EverMe agent token.
- Stop dropping Codex tool families and non-main OpenClaw agents during import.
- Bump the `@everme/cli` npm wrapper to 0.32.0 so wrapper and binary versions
match, and print a per-host install hint from its postinstall refresh.
- Format the tree with `gofmt` and tidy `go.mod` / `go.sum`.

- Rework `evercli plugin install hermes` to install a native Hermes
`MemoryProvider` plugin instead of an MCP server entry. The Python provider
is embedded in the `evercli` binary (`cli/internal/plugin/hermesassets/`)
Expand All @@ -32,6 +52,23 @@ the open-source home for EverMe CLI and agent plugins.

### Plugins

- Release the protocol packages at 0.6.1 (from 0.4.2).
- Open-source four more host plugins: `@everme/kimicode`, `@everme/cursor`,
`@everme/devin`, and `@everme/dsh` (DeepSeek Harness), each with its own test
suite in the npm workspace.
- Refresh the Codex marketplace plugin (`plugins/everme`) to 0.6.1 so
`codex plugin marketplace upgrade EverMind-AI/EverMe` picks up the current
lifecycle Hook runner — the marketplace reads this repository directly, so
the npm releases alone never reached Codex users. The bundled
`bin/hook.mjs` is rebuilt from `plugins/codex/scripts/build-marketplace.mjs`
and is byte-identical to the runner published on npm.
- `@everme/agent-sdk`: give lifecycle hooks a time budget that fits inside the
host's kill deadline, and fire the watchdog after the request deadline rather
than before it.
- Surface one trace id across plugin logs and tool results.
- Close the v2 first-flush gap so the opening turn of a session is extracted
instead of silently dropped.

- Release the protocol packages at 0.4.2. `@everme/agent-sdk` now builds the
recall query from the user's intent instead of the host's raw prompt
(stripping injected reminders and host boilerplate before searching), and
Expand Down Expand Up @@ -80,6 +117,10 @@ the open-source home for EverMe CLI and agent plugins.

### Docs

- Ship `cli/.goreleaser.yml` so the published binaries are reproducible from
this tree, and correct its release-notes header, which still described the
distribution as closed-source.

- Add root `README.md` and `README.zh.md`.
- Add `CONTRIBUTING.md`.
- Add `AGENTS.md` with contribution goals, pre-PR checks, source layout, and
Expand All @@ -91,6 +132,13 @@ the open-source home for EverMe CLI and agent plugins.

### CI

- Validate all ten workspace manifests in `fast-gate`, not just the original
six.
- Exempt the import redactor and its fixtures from the private-key scan. The
redactor exists to strip PEM blocks, so it necessarily contains the header
pattern the scan looks for, and its fixture bodies are fabricated
placeholders the tests assert get replaced.

- Add layered GitHub Actions CI inspired by `larksuite/cli`:
`fast-gate`, `cli-test`, `plugin-test`, `coverage`, `package-smoke`,
`security`, and a final `results` gate.
Expand All @@ -100,6 +148,11 @@ the open-source home for EverMe CLI and agent plugins.

### Security

- Pin `hono`, `fast-uri`, and `ip-address` to patched floors through workspace
`overrides`, clearing advisories that reach the tree via
`@modelcontextprotocol/sdk`. The published package manifests are untouched —
each pin stays inside its consumer's declared range.

- Add `SECURITY.md` with private vulnerability reporting guidance.
- Expand `.gitignore` for local env files, logs, build artifacts, Node
dependency directories, and editor state.
Expand Down
70 changes: 70 additions & 0 deletions cli/.goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
version: 2

project_name: evercli

# monorepo: this config is intentionally scoped to cli/. Run goreleaser
# with `cd cli && goreleaser release --clean` (CI sets workdir: cli).
# Tag scheme: bare semver `vX.Y.Z`.

builds:
- id: evercli
main: ./
binary: evercli
env:
- CGO_ENABLED=0
flags:
- -trimpath
- -buildvcs=false
goos:
- darwin
- linux
- windows
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X main.version={{.Version}}
- -X main.commit={{.Commit}}
- -X main.date={{.Date}}

archives:
- format: tar.gz
name_template: >-
{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}
format_overrides:
- goos: windows
format: zip
# Force binary-only archives: goreleaser v2 auto-includes README*/
# LICENSE*/CHANGELOG* when `files` is missing OR empty list, so we
# use a glob that matches nothing to suppress the defaults. Docs are
# read from the repository, not shipped inside the archive.
files:
- src: nothing-here-do-not-match-do-not-remove*

checksum:
name_template: sha256sums.txt
algorithm: sha256

release:
github:
owner: EverMind-AI
name: EverMe
prerelease: false
header: |
## EverMe CLI

Prebuilt `evercli` binaries for AI Agents (Claude Code, OpenClaw, Codex, …).
Source lives in [`cli/`](https://github.com/EverMind-AI/EverMe/tree/main/cli)
under Apache-2.0.

### Install (recommended)

```bash
npm install -g @everme/cli
```

Or download an archive below and unpack manually.

changelog:
disable: true
76 changes: 65 additions & 11 deletions cli/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
- Build: `make build` from `cli/`, or `make -C cli build` from repo root → `cli/_output/evercli`
- Test: `make test` (unit + contract)
- Dev: `cd cli && go run . <args>` (or `make dev ARGS="auth status"`)
- Public contract: `/docs/contracts.md`

This file is self-contained and governs `cli/` only — it references no files outside this directory.

## Command surface (post-slim)

Four subcommands, intentionally minimal:
Five subcommands, intentionally minimal:

- `auth` — login / logout / status / me
- `plugin` — list / install (Claude Code, OpenClaw)
- `import` — scan / run (cold-start memory upload)
- `plugin` — list / install / uninstall (Claude Code, OpenClaw, Cursor, Claude Desktop, Codex, Hermes, Devin, WorkBuddy, opencode, Kimi Code, Raven)
- `import` — conversations scan / run (cold-start session + markdown import)
- `doctor` — slim self-checks (network reachability + credential backend)
- `skill` — browse / install / manage EverMe skills

Binary identity is exposed via `evercli --version` (cobra-native flag).
The slimming pass also retired:
- `evercli onboard` — users run `auth login` → `plugin install` → `import run` manually
- `evercli plugin uninstall` — users disconnect agents from the EverMe web UI and clean up host plugin entries by hand
The slimming passes also retired:
- `evercli onboard` — users run `auth login` → `plugin install` → `import conversations run` manually
- `evercli agents disconnect` — `plugin uninstall <platform>` covers the cloud disconnect; there is no standalone revoke command (Web UI remains the manual fallback)
- `evercli plugin scan` (and the post-success background scan after login/install/import) — replaced by an update-time hint: the npm wrapper's postinstall refresh (`plugins/cli/scripts/upgrade-plugins.js`) prints one line per detected host that has no EverMe entry, with the exact `evercli plugin install <platform>` command
- `evercli version` / `update` / `config` / `debug` subcommands
- `doctor --print-skills` / `--cleanup` flavors

Expand All @@ -29,16 +32,67 @@ Reintroduce any of these only with a documented user need.

```bash
evercli auth login # Device Flow; --no-wait + --device-code for AI Agents
evercli plugin install claude-code # or `openclaw`; rotates evt + writes the host plugin entry (Claude Code MCP / OpenClaw plugins.entries)
evercli import run # cold-start memory upload (optional)
evercli plugin install claude-code # or `openclaw` / `dsh`; rotates evt + writes the host integration
evercli import conversations run # cold-start session + markdown import (optional)
```

**Kimi Code is one CLI command + one TUI step** (not fully hands-off). Kimi
Code has no headless *registration* command (`/plugins install` is TUI-only)
and its `plugins/installed.json` record is an internal, manifest-embedding
format we don't hand-write. So `evercli plugin install kimicode` does the
credential + bundle work — including auto-running `npm install -g
@everme/kimicode` when the bundle isn't already on disk (mirrors claude-code;
fail-hard if npm is missing) — and the user finishes *registration* inside
Kimi Code:

```bash
evercli plugin install kimicode # rotates evt → writes ~/.kimi-code/everme.env (0600)
# + `npm install -g @everme/kimicode` if the bundle is missing
# + stages the bundle (with node_modules) at ~/.kimi-code/everme/
# then, inside the Kimi Code TUI:
# /plugins install ~/.kimi-code/everme ← Kimi Code copies it to plugins/managed/ + writes the record
# /plugins reload (or start a new session)
```

## Manual uninstall flow (replaces `plugin uninstall`)
**DeepSeek Harness supports both Web and Headless through native Cordis hooks + MCP**: `evercli plugin install dsh` prefers the installed `dsh` launcher and falls back to `npx --yes @deepseek-ai/dsh@latest`, refreshes the `@everme/dsh@latest` bundle in both the `web` and `headless` profiles, writes an MCP insertion block to each profile that starts `@everme/memory-mcp@latest` through `npx`, and stores their shared credentials in `~/.dsh/.env` with mode `0600`. DSH installs receive a five-minute minimum operation budget so a cold npm fallback is not clipped by EverCLI's default 60-second command timeout. The native plugin performs automatic recall on `agent/pre-step` and saves complete turns from `session/event`; `session/flush` ensures the one-shot Headless runner waits for the upload before exiting. DSH scrubs inherited credential-shaped variables for stdio servers, so both MCP configs explicitly re-add the three EverMe variables from that env file. Restart Web sessions after install if their patch watcher has not reloaded the change; subsequent Headless runs load the updated profile directly.

**Raven is fully headless** but single-slot: `evercli plugin install raven`
drops the embedded Python backend at `~/.raven/plugins/everme-memory/` and
patches `~/.raven/config.json` (`memory.backend=everme` +
`plugins.config["everme-memory"]` credentials — Raven's config.json is its
canonical credential store, so there is no everme.env). Selecting `everme`
supersedes Raven's bundled `everos` local-memory backend for the session
(same exclusivity as OpenClaw's contextEngine slot); the pre-install config
is kept at `config.json-bak`. Requires a Raven version whose plugin registry
adds user-dir plugins to `sys.path` before factory import — older versions
discover the manifest but fail the `everme_raven` import at boot.

## Uninstall flow

`evercli plugin uninstall <platform>` performs local cleanup first and then
disconnects the cloud agent whose platform AND machine fingerprint exactly
match this machine. It never guesses: when no agent carries this machine's
fingerprint, nothing is disconnected and the result reports
`noMatchingCloudAgent` plus a NextSteps pointer at the Web UI — revoking a
fingerprint-less agent could kill another machine's token. It never deletes
an entire host config or another plugin's state. Every supported platform's
writer implements the `Remover` interface — including Hermes
(`internal/plugin/hermes.go`), which clears `memory.provider`, drops the
legacy `mcp_servers` entry, and removes `~/.hermes/plugins/everme/` +
`everme.env`. In an interactive tty the command asks a y/N confirmation
(default No) unless `--yes` is passed; `--no-prompt` requires `--yes`;
`--keep-agent` skips the cloud disconnect. There is no standalone
cloud-revoke command; disconnecting without local cleanup is a Web UI action.

If the CLI is unavailable, the manual fallback is:

1. Disconnect the agent in the EverMe web UI (account → agents → revoke).
2. Remove the host plugin entry:
- Claude Code: `claude plugin uninstall everme && claude plugin marketplace remove everme && rm ~/.claude/everme.env`
- OpenClaw: edit `~/.openclaw/openclaw.json` and drop everything `plugin install openclaw` wrote — `plugins.entries["@everme/openclaw"]` (the per-agent config), `plugins.slots.contextEngine` (the slot binding), and `"@everme/openclaw"` from `plugins.allow`. The plugin id mirrors `cli/internal/plugin/openclaw.go:OpenClawPluginID` — keep them in sync if it ever moves.
- Kimi Code: in the TUI run `/plugins remove everme`, then `rm -rf ~/.kimi-code/everme ~/.kimi-code/everme.env`.
- Raven: edit `~/.raven/config.json` — restore `memory.backend` to its previous value (see `config.json-bak`) and drop `plugins.config["everme-memory"]` — then `rm -rf ~/.raven/plugins/everme-memory`. The plugin id mirrors `cli/internal/plugin/raven.go:RavenPluginID` — keep them in sync if it ever moves.
- DeepSeek Harness: run `dsh plugin --profile <web|headless> remove @everme/dsh` for both managed profiles, then remove only the evercli-managed blocks from each profile's `cordis.patch.yml` and from `~/.dsh/.env`; preserve every unrelated patch and env entry. If a patch becomes empty, leave `[]`; if the env file becomes empty, remove it.

## Layered import rules

Expand All @@ -55,7 +109,7 @@ Business packages (`auth`, `plugin`, `importer`) **do not import each other**; t

## Output contract is sacred

`internal/output/` defines the AI-Agent ABI (envelope shape, exit codes, error type taxonomy). Changing field names, exit code semantics, or `error.type` values is a breaking change. Update `/docs/contracts.md` together with code, and refresh golden test fixtures in `internal/output/testdata/golden/`.
`internal/output/` defines the AI-Agent ABI (envelope shape, exit codes, error type taxonomy). Changing field names, exit code semantics, or `error.type` values is a breaking change. Refresh the golden test fixtures in `internal/output/testdata/golden/` together with the code.

## stdout vs stderr

Expand Down
30 changes: 19 additions & 11 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

EverMe cloud-memory CLI for AI Agents (Claude Code, OpenClaw, …).

> Public AI-agent contract: [`docs/contracts.md`](../docs/contracts.md).
> Conventions: [`AGENTS.md`](AGENTS.md). Public AI-agent
> contract: [`docs/contracts.md`](../docs/contracts.md).

## Build & run

Expand All @@ -16,8 +17,8 @@ make test

```bash
evercli auth login # Device Flow; AI Agents pass --no-wait + --device-code
evercli plugin install claude-code # or `openclaw`; rotates evt + writes MCP config
evercli import run # optional cold-start memory upload
evercli plugin install claude-code # or `openclaw` / `dsh`; rotates evt + writes host config
evercli import conversations run # optional cold-start session + markdown import
evercli doctor # connectivity + credential health check
evercli --version # build identity
```
Expand All @@ -27,15 +28,22 @@ evercli --version # build identity
| Command | Purpose |
|-----------|------------------------------------------------------|
| `auth` | login / logout / status / me |
| `plugin` | list / install (Claude Code, OpenClaw) |
| `import` | scan / run (cold-start memory upload) |
| `plugin` | list / install / uninstall (Claude Code, OpenClaw, Cursor, Claude Desktop, Codex, DeepSeek Harness, Hermes, Devin, WorkBuddy, opencode, Kimi Code, Raven) |
| `import` | conversations scan / run (cold-start session + markdown import) |
| `doctor` | minimal self-checks (connectivity + credential) |

Retired in the slimming pass and replaced by the manual flow above:
`onboard`, `plugin uninstall`, `version` subcommand, `update`,
`config`, `debug bundle`. Reintroduce only on documented user need.
See [`AGENTS.md`](AGENTS.md) for the manual install / uninstall
sequences.
| `skill` | browse / install / manage EverMe skills |

`plugin uninstall <platform>` is back after the slimming pass: it removes
only EverMe-owned local state (config entry, hooks, everme.env) and then
disconnects the cloud agent matching this machine's fingerprint
(`--keep-agent` skips the disconnect). Devin installs land the shared MCP
entry plus a native `post_cascade_response_with_transcript` lifecycle
hook in `hooks.json` next to `~/.codeium/windsurf/mcp_config.json`. DeepSeek Harness installs add the `@everme/dsh` bundle to the Web profile for native Cordis recall/save hooks and keep `@everme/memory-mcp` available as the stdio tool server.

Still retired and replaced by the manual flow above: `onboard`,
`version` subcommand, `update`, `config`, `debug bundle`. Reintroduce
only on documented user need. See [`AGENTS.md`](AGENTS.md) for the
manual install / uninstall sequences.

## Contributor notes

Expand Down
Loading
Loading