d90abde29e
Rename echo-memory/ECHO -> quicksilver/Quicksilver throughout and make the plugin self-configuring per operator: - First-run flow: prompt for endpoint FQDN, API key, and operator name/role; verify; persist to a local config file (~/.quicksilver/quicksilver-config.json). - Two-layer setup detection: local config (is this install configured?) + in-vault marker (is the vault scaffolded?). Key never stored in the vault. - Replace hardcoded endpoint/key in all curl examples with $BASE/$AUTH loaded from the config file. - Genericize all "Jason"/"Bryan goldbrain"/MPM/wISP references to "the operator"; keep Jason as architect credit (README + plugin.json author). - Personalize memory to the configured operator (name/role seeded into operator-preferences and the vault marker). - Add echo-vault.md -> quicksilver-vault.md rename migration. - Rebuild packaged quicksilver.plugin; add docs/quicksilver-plan.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
141 lines
7.4 KiB
Markdown
141 lines
7.4 KiB
Markdown
# Quicksilver — user-agnostic rewrite + rename plan
|
|
|
|
## Objective
|
|
|
|
Turn the plugin (formerly `echo-memory` / "ECHO") into one a coworker can install
|
|
cold. On first run it detects it's freshly installed, prompts for the **API endpoint
|
|
FQDN**, **API key**, and **operator name/role**, verifies them, persists them to a
|
|
**local bootstrap indicator file**, then bootstraps the vault and personalizes memory
|
|
to that operator. The system is renamed to **Quicksilver** throughout. Jason stays
|
|
credited only as the architect.
|
|
|
|
## Locked decisions
|
|
|
|
1. **Credentials** → a dedicated **local bootstrap indicator file** (client-side) holds
|
|
FQDN + API key. The in-vault marker stays a pure schema/version flag (no secret).
|
|
2. **Operator identity** → prompt for name/role at first run; personalize memory
|
|
("Alex prefers X"); seed `operator-preferences.md` + the marker with it.
|
|
3. **Attribution** → Jason kept in `plugin.json` `author` + a one-line
|
|
"Architecture by Jason Stedwell" credit in the README. Every other operational
|
|
mention removed.
|
|
4. **Name** → full rename `echo-memory` / `ECHO` → `quicksilver` / `Quicksilver`
|
|
(0 "echo" hits after the pass).
|
|
|
|
## Core design: two-layer "is this set up?" detection
|
|
|
|
| Layer | File | Question | Holds |
|
|
|---|---|---|---|
|
|
| 1. Local indicator (new) | `~/.quicksilver/quicksilver-config.json` (client-side) | "Is *this install* configured?" | FQDN + **API key** + operator name/role |
|
|
| 2. Vault marker (existing) | `_agent/quicksilver-vault.md` (in vault) | "Is the *vault* scaffolded?" | schema_version, bootstrap date, operator name — **never the key** |
|
|
|
|
The secret lives client-side (you need it *before* you can reach the vault, and the
|
|
plugin's own safety rule forbids keys in vault notes). The vault marker stays a pure
|
|
schema flag. The local indicator file *is* the "freshly installed?" signal — its
|
|
absence triggers first-run.
|
|
|
|
### Local indicator file spec
|
|
|
|
Path: `~/.quicksilver/quicksilver-config.json` (Windows:
|
|
`%USERPROFILE%\.quicksilver\quicksilver-config.json`). Lives in the user home, **not**
|
|
the plugin dir, so it survives plugin reinstalls/updates.
|
|
|
|
```json
|
|
{
|
|
"schema": 1,
|
|
"endpoint": "https://<operator-fqdn>",
|
|
"api_key": "<bearer-token>",
|
|
"operator": { "name": "Alex Rivera", "role": "Network Engineer" },
|
|
"configured_at": "2026-06-07",
|
|
"verified_at": "2026-06-07"
|
|
}
|
|
```
|
|
|
|
The skill reads this with the Read tool at session start and substitutes
|
|
`endpoint`→`$BASE` and `api_key`→bearer into all curl calls. **No `jq` dependency** —
|
|
the agent parses the JSON itself, portable across Windows/Mac/Linux shells.
|
|
|
|
## First-run / session-start algorithm (new Step 0)
|
|
|
|
1. **Check local indicator** (`~/.quicksilver/quicksilver-config.json`).
|
|
- **Absent → FRESH INSTALL.** Tell the operator this looks like a first run and
|
|
prompt for: (a) endpoint FQDN, (b) API key, (c) name + role. Verify by probing
|
|
`GET $BASE/vault/_agent/quicksilver-vault.md` (200/404 = reachable+authorized;
|
|
connection error/401 = re-prompt). Write the indicator file (`chmod 600`).
|
|
- **Present →** load `endpoint`, `api_key`, `operator`; continue.
|
|
2. **Probe vault marker** `_agent/quicksilver-vault.md` with the known creds.
|
|
- **404 →** fresh bootstrap (scaffold), seeding `operator-preferences.md`
|
|
`## Operator` with the provided name/role, and writing the marker with
|
|
`operator:` set (no key).
|
|
- **200 →** check `schema_version`, migrate if stale, proceed to normal loading.
|
|
|
|
## File-by-file changes (genericize + rename in one pass)
|
|
|
|
- **`.claude-plugin/plugin.json`** — `name`/`description`/`keywords` → quicksilver;
|
|
drop "Jason's personal memory vault"; **keep** `author: Jason Stedwell`; bump
|
|
`0.5.0` → `0.6.0`.
|
|
- **`README.md`** — title `# quicksilver`; operator-agnostic intro + one line
|
|
"Architecture by Jason Stedwell."; rewrite **Configuration** (no hardcoded
|
|
server/key; document first-run flow + indicator file); remove "not for
|
|
distribution"; ECHO → Quicksilver.
|
|
- **`skills/quicksilver/SKILL.md`** — frontmatter `name: quicksilver`, genericize
|
|
`description` (strip Jason / Bryan's goldbrain / MPM / wISP; ECHO → Quicksilver);
|
|
replace hardcoded `OBSIDIAN_BASE`/`OBSIDIAN_KEY` block with "load from indicator
|
|
file"; delete the `echoapi.alwisp.com`-only / retired-`obsidian-memory` paragraph;
|
|
rewrite operator-identity paragraph to read identity dynamically; every curl
|
|
`Bearer 2412…`→`$AUTH`, `https://echoapi.alwisp.com`→`$BASE`; remove goldbrain/Bryan
|
|
cross-write rule; "Jason" → "the operator"; add Step 0 to loading; marker path →
|
|
`quicksilver-vault.md`.
|
|
- **`references/api-reference.md`** — server/key header lines and every curl →
|
|
`$BASE`/`$AUTH`; example prose genericized; marker path.
|
|
- **`references/bootstrap.md`** — replace hardcoded `AUTH`/`BASE` with load-from-
|
|
indicator preamble; add **Step 0: Client configuration (first run)**; seed
|
|
`## Operator` from provided name; marker stores operator + schema only; add the
|
|
`echo-vault.md` → `quicksilver-vault.md` rename migration.
|
|
- **`references/vault-layout.md`** — genericize operator-preferences + people example
|
|
(`<operator-name>.md`); marker path; ECHO → Quicksilver.
|
|
- **`references/operating-contract.md`** — confirm operator-agnostic; ECHO →
|
|
Quicksilver.
|
|
- **`references/session-log-template.md`** — update illustrative key/decision lines;
|
|
example slugs `echo-*` → `quicksilver-*`.
|
|
- **`scaffold/quicksilver-vault.md`** (was `echo-vault.md`) — "Quicksilver Vault
|
|
Marker"; add `operator:` frontmatter; `managed_by: quicksilver-plugin`; explicit
|
|
"no key here".
|
|
- **`scaffold/README.vault.md`** — "Quicksilver Memory Vault"; ECHO → Quicksilver.
|
|
- **`scaffold/anchors/operator-preferences.seed.md`** — add `{{OPERATOR}}`/`{{ROLE}}`
|
|
substitution tokens for `## Operator`.
|
|
- **`scaffold/anchors/inbox.seed.md`** — "quicksilver skill".
|
|
|
|
## Path / file renames (git mv)
|
|
|
|
- `echo-memory.plugin.src/` → `quicksilver.plugin.src/`
|
|
- `…/skills/echo-memory/` → `…/skills/quicksilver/`
|
|
- `…/scaffold/echo-vault.md` → `…/scaffold/quicksilver-vault.md`
|
|
- `echo-memory.plugin` (packaged artifact) → rebuilt/renamed `quicksilver.plugin`
|
|
|
|
## Migration impact (Jason's existing vault)
|
|
|
|
The marker rename means Jason's current vault has the marker at the old path. Fold into
|
|
the schema migration: on probe, if `quicksilver-vault.md` is 404 **but**
|
|
`echo-vault.md` is 200, treat as a rename migration — PUT the new marker, DELETE the
|
|
old, scrub stale `[[echo-vault]]` links. New coworker vaults are fresh and hit the
|
|
clean path.
|
|
|
|
## Security / hygiene
|
|
|
|
- **Rotate the live key.** `241265fbe…` is committed in plaintext and in git history.
|
|
Even after genericizing, history retains it — rotate it on the backend.
|
|
- Indicator file holds a secret → write `0600`; it lives in `$HOME`, outside the repo.
|
|
|
|
## Validation
|
|
|
|
- **Grep gate:** `grep -ri "echo"` → 0 hits; `grep -ri "jason\|alwisp\|241265\|goldbrain\|bryan"` → only README architect credit + plugin.json author.
|
|
- **Fresh install:** no indicator + empty vault → prompts for FQDN/key/name, file
|
|
written, vault scaffolded, `## Operator` seeded.
|
|
- **Returning user:** indicator + marker present → loads silently, no prompts.
|
|
- **Reinstall:** plugin reinstalled, indicator persists in `$HOME` → no re-prompt.
|
|
- **Bad endpoint at first run:** unreachable/401 → graceful re-prompt, nothing written.
|
|
|
|
## Out of scope (v1)
|
|
|
|
Multiple operators / multiple vaults per machine (single indicator file assumed).
|