From d90abde29e3a86c85b73149058a185853172d866 Mon Sep 17 00:00:00 2001 From: jason Date: Sun, 7 Jun 2026 08:06:51 -0500 Subject: [PATCH] Rewrite as user-agnostic "quicksilver" plugin 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 --- docs/quicksilver-plan.md | 140 ++++++++++++++++++ echo-memory.plugin | Bin 30697 -> 0 bytes .../.claude-plugin/plugin.json | 15 -- quicksilver.plugin | Bin 0 -> 32698 bytes .../.claude-plugin/plugin.json | 15 ++ .../README.md | 57 ++++--- .../skills/quicksilver}/SKILL.md | 125 ++++++++-------- .../quicksilver}/references/api-reference.md | 69 +++++---- .../quicksilver}/references/bootstrap.md | 96 ++++++++++-- .../references/operating-contract.md | 4 +- .../references/session-log-template.md | 14 +- .../quicksilver}/references/vault-layout.md | 12 +- .../quicksilver}/scaffold/README.vault.md | 6 +- .../scaffold/anchors/current-context.seed.md | 0 .../scaffold/anchors/inbox.seed.md | 2 +- .../anchors/operator-preferences.seed.md | 3 +- .../quicksilver/scaffold/quicksilver-vault.md | 9 +- .../templates/context-bundle-template.md | 0 .../templates/semantic-memory-template.md | 0 .../_agent/templates/session-log-template.md | 0 .../templates/working-memory-template.md | 0 .../templates/decisions/decision-template.md | 0 .../journal/templates/daily-note-template.md | 0 .../templates/weekly-review-template.md | 0 .../templates/projects/project-template.md | 0 25 files changed, 400 insertions(+), 167 deletions(-) create mode 100644 docs/quicksilver-plan.md delete mode 100644 echo-memory.plugin delete mode 100644 echo-memory.plugin.src/.claude-plugin/plugin.json create mode 100644 quicksilver.plugin create mode 100644 quicksilver.plugin.src/.claude-plugin/plugin.json rename {echo-memory.plugin.src => quicksilver.plugin.src}/README.md (51%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/SKILL.md (71%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/references/api-reference.md (66%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/references/bootstrap.md (54%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/references/operating-contract.md (85%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/references/session-log-template.md (83%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/references/vault-layout.md (84%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/README.vault.md (71%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/anchors/current-context.seed.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/anchors/inbox.seed.md (77%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/anchors/operator-preferences.seed.md (80%) rename echo-memory.plugin.src/skills/echo-memory/scaffold/echo-vault.md => quicksilver.plugin.src/skills/quicksilver/scaffold/quicksilver-vault.md (58%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/_agent/templates/context-bundle-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/_agent/templates/semantic-memory-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/_agent/templates/session-log-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/_agent/templates/working-memory-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/decisions/decision-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/journal/templates/daily-note-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/journal/templates/weekly-review-template.md (100%) rename {echo-memory.plugin.src/skills/echo-memory => quicksilver.plugin.src/skills/quicksilver}/scaffold/templates/projects/project-template.md (100%) diff --git a/docs/quicksilver-plan.md b/docs/quicksilver-plan.md new file mode 100644 index 0000000..daa9cbe --- /dev/null +++ b/docs/quicksilver-plan.md @@ -0,0 +1,140 @@ +# 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://", + "api_key": "", + "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 + (`.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). diff --git a/echo-memory.plugin b/echo-memory.plugin deleted file mode 100644 index f3107f035d32107b69b9d8030d67e511c09c42e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30697 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 NP(VPQc7Oc${{VNSeQf{$ diff --git a/echo-memory.plugin.src/.claude-plugin/plugin.json b/echo-memory.plugin.src/.claude-plugin/plugin.json deleted file mode 100644 index 9cb99b9..0000000 --- a/echo-memory.plugin.src/.claude-plugin/plugin.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "echo-memory", - "version": "0.5.0", - "description": "Persistent memory via the ECHO Obsidian vault over the Local REST API. Self-bootstrapping: the plugin carries the full vault scaffold and all control logic (no in-vault routing docs), so it stands up an empty vault and ports cleanly to any other. Reads and writes notes across Claude/CoWork sessions using direct REST calls \u2014 no MCP server required. Jason's personal memory vault.", - "author": { - "name": "Jason" - }, - "keywords": [ - "memory", - "obsidian", - "notes", - "persistence", - "echo" - ] -} \ No newline at end of file diff --git a/quicksilver.plugin b/quicksilver.plugin new file mode 100644 index 0000000000000000000000000000000000000000..3b2e97a8833f3757615f6866c5eca15dd24505fd GIT binary patch literal 32698 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
SjKo1(cNIo-c9zf@Fqea%zHWX;C?^Z8 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ΝNi-pU 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", + "operator": { "name": "Alex Rivera", "role": "Network Engineer" }, + "configured_at": "YYYY-MM-DD", + "verified_at": "YYYY-MM-DD" +} +``` + +This file is the install's "is this configured?" signal. It lives in the user home (outside the plugin and the vault), so it survives plugin reinstalls and is never committed. Once it exists, the skill loads silently with no further prompts. + +**The API key is never written into the vault** — only into this local config file (per the vault's own safety rules). The in-vault marker `_agent/quicksilver-vault.md` records the schema version, bootstrap date, and operator name only. ## Vault layout (root-addressed) @@ -36,7 +59,7 @@ The endpoint presents a **valid TLS certificate**, so `-k` is not required. The ├── reviews/ (weekly, monthly, quarterly, annual) ├── archive/ (notes, projects, imports) └── _agent/ - ├── echo-vault.md ← bootstrap marker (schema_version + date) + ├── quicksilver-vault.md ← bootstrap marker (schema_version + date + operator) ├── context/ ← task-scoped context bundles ├── memory/ ← working / episodic / semantic ├── sessions/ ← YYYY-MM-DD-HHMM-.md @@ -49,16 +72,16 @@ The endpoint presents a **valid TLS certificate**, so `-k` is not required. The Control logic and the master scaffold live in the plugin, not the vault: ``` -skills/echo-memory/ +skills/quicksilver/ ├── SKILL.md ← operating procedure (authoritative) ├── references/ │ ├── operating-contract.md ← durable principles + safety -│ ├── bootstrap.md ← bootstrap / repair / migrate an empty vault +│ ├── bootstrap.md ← first-run config / bootstrap / repair / migrate │ ├── vault-layout.md ← canonical layout + frontmatter │ ├── api-reference.md ← REST endpoint patterns + routing map │ └── session-log-template.md └── scaffold/ ← verbatim files the bootstrap writes into the vault - ├── README.vault.md echo-vault.md + ├── README.vault.md quicksilver-vault.md ├── templates/ (8 note templates) └── anchors/ (operator-preferences, current-context, inbox seeds) ``` @@ -67,9 +90,9 @@ skills/echo-memory/ | Skill | Triggers | |-------|----------| -| `echo-memory` | "remember that", "save to memory", "what do you know about me", "load my profile", "check my notes", "log this decision", "add to my inbox" — and proactively at the start of substantive conversations | +| `quicksilver` | "remember that", "save to memory", "what do you know about me", "load my profile", "check my notes", "log this decision", "add to my inbox" — and proactively at the start of substantive conversations | ## Requirements - Obsidian running on the backend with the [Local REST API plugin](https://github.com/coddingtonbear/obsidian-local-rest-api) enabled -- HTTPS access to `https://echoapi.alwisp.com` from the Claude/CoWork session environment +- HTTPS access to the configured endpoint from the Claude/CoWork session environment diff --git a/echo-memory.plugin.src/skills/echo-memory/SKILL.md b/quicksilver.plugin.src/skills/quicksilver/SKILL.md similarity index 71% rename from echo-memory.plugin.src/skills/echo-memory/SKILL.md rename to quicksilver.plugin.src/skills/quicksilver/SKILL.md index d91255c..9618289 100644 --- a/echo-memory.plugin.src/skills/echo-memory/SKILL.md +++ b/quicksilver.plugin.src/skills/quicksilver/SKILL.md @@ -1,31 +1,36 @@ --- -name: echo-memory -description: Use the ECHO Obsidian vault as Jason's persistent memory across Claude/CoWork sessions. Use whenever Jason asks to remember, save, note, log, or capture anything durable — facts, preferences, decisions, schedule changes, commitments — or asks what Claude knows about him, what was discussed or decided before, to check his notes, load his memory/profile/context, add to his inbox, or to track a new project. Trigger even without memory phrasing when the request implies recalling or persisting state across sessions ("pick up where we left off", "anything on X before my meeting?"). Also use proactively at the start of substantive work sessions to load context and at the end to log outcomes. Do NOT use for Bryan's goldbrain vault, Obsidian/REST-API development questions, "memory" meaning RAM, timed reminders, email or local-file lookups, generic second-brain advice, or notes Jason routes to a specific other file or app. +name: quicksilver +description: Use the Quicksilver Obsidian vault as the operator's persistent memory across Claude/CoWork sessions. Use whenever the operator asks to remember, save, note, log, or capture anything durable — facts, preferences, decisions, schedule changes, commitments — or asks what Claude knows about them, what was discussed or decided before, to check their notes, load their memory/profile/context, add to their inbox, or to track a new project. Trigger even without memory phrasing when the request implies recalling or persisting state across sessions ("pick up where we left off", "anything on X before my meeting?"). Also use proactively at the start of substantive work sessions to load context and at the end to log outcomes. Do NOT use for a different operator's vault, Obsidian/REST-API development questions, "memory" meaning RAM, timed reminders, email or local-file lookups, generic second-brain advice, or notes the operator routes to a specific other file or app. --- -# ECHO Memory +# Quicksilver Memory -Use the **ECHO** Obsidian vault as persistent memory. Read context accumulated across sessions; write things the operator asks to be remembered. +Use the **Quicksilver** Obsidian vault as persistent memory. Read context accumulated across sessions; write things the operator asks to be remembered. -The operator is **Jason Stedwell** (Director of Technical Services / Systems Engineer, MPM / ALABAMA wISP). Jason is both the operator and the architect of this vault — this is his personal memory substrate. Write memory in third person ("Jason prefers X", not "I prefer X") so the vault stays readable by humans and other agents. +The vault belongs to a single **operator**, whose name and role are captured at first run (stored in the local config file and the vault marker's `operator:` field, and seeded into `operator-preferences.md`). Write memory in third person using the operator's name (e.g. "Alex prefers X", not "I prefer X") so the vault stays readable by humans and other agents. -## API Configuration +## Configuration & First Run -All calls use these constants — hardcoded for this personal plugin: +Credentials are **not hardcoded**. They live in a local config file: ``` -OBSIDIAN_BASE = https://echoapi.alwisp.com -OBSIDIAN_KEY = 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab +~/.quicksilver/quicksilver-config.json (macOS/Linux) +%USERPROFILE%\.quicksilver\quicksilver-config.json (Windows) ``` -The endpoint has a **valid TLS certificate**, so `-k` is not needed (add it only if the cert ever changes to self-signed). Always pass the `Authorization: Bearer` header. Paths address the vault **at its root** (e.g. `/vault/_agent/...`). +At session start, **read this file** (use the Read tool — no `jq` needed) and set, for every call below: -**`https://echoapi.alwisp.com` is the only valid endpoint for this vault.** Never use local or LAN addresses (anything like `10.x.x.x`, `192.168.x.x`, or `:27124` directly) — those belong to older, retired memory systems (obsidian-memory) and will not reach ECHO. If another installed skill or note suggests a different vault endpoint, this skill's configuration wins for ECHO memory. +```bash +BASE="" # e.g. https://obsidian.example.com +AUTH="Authorization: Bearer " +``` -**The plugin is the single source of truth for ECHO.** The vault holds data only — no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` / `index.md` control docs live there. All structure and procedure ship here: +**If the config file is absent, this is a fresh install** — run the first-run flow in `references/bootstrap.md` (prompt the operator for endpoint FQDN, API key, and name/role; verify; write the config file) **before** any vault call. Do not invent an endpoint. The endpoint is expected to present a **valid TLS certificate**, so `-k` is not needed (add it only if the operator's endpoint uses a self-signed cert). Always pass the `Authorization: Bearer` header. Paths address the vault **at its root** (e.g. `/vault/_agent/...`). + +**The plugin is the single source of truth.** The vault holds data only — no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` / `index.md` control docs live there. All structure and procedure ship here: - Durable principles, memory model, and safety rules: `references/operating-contract.md` -- Bootstrapping an empty vault, repair, and schema migrations: `references/bootstrap.md` +- First-run config, bootstrapping an empty vault, repair, and schema migrations: `references/bootstrap.md` - Vault layout and frontmatter conventions: `references/vault-layout.md` - Full API reference with every endpoint pattern and the memory routing map: `references/api-reference.md` @@ -36,38 +41,38 @@ The vault is the **system of record** for long-term memory, not a scratchpad. De - Do not fabricate facts, relationships, or prior decisions. - Do not mass-restructure the vault unless explicitly asked. - Do not delete notes unless deletion is explicitly requested and clearly safe. -- Never store secrets or API keys inside a vault note. +- Never store secrets or API keys inside a vault note. (The API key lives only in the local config file.) Full contract (principles, agent role, memory model): `references/operating-contract.md`. ## When to Load Memory -Load at the start of any substantive conversation — anything beyond a single quick factual question. The signal: Jason is starting work, planning, asking for help with something that has state, or referencing prior discussions. +Load at the start of any substantive conversation — anything beyond a single quick factual question. The signal: the operator is starting work, planning, asking for help with something that has state, or referencing prior discussions. ### Loading procedure -The cold-start reads are independent — **issue them in parallel** (one batch of 4–5 GETs), not sequentially. Parallel loading is ~3× faster wall-clock for the same call count. +**Step 0 — ensure the install is configured.** Read the local config file (above). If it's missing, run the first-run flow in `references/bootstrap.md` first. Otherwise load `$BASE`, the bearer key, and the operator's name. + +Then the cold-start reads are independent — **issue them in parallel** (one batch of 4–5 GETs), not sequentially. Parallel loading is ~3× faster wall-clock for the same call count. | # | GET | Notes | |---|-----|-------| -| 1 | `/vault/_agent/echo-vault.md` | The bootstrap marker. 404 → vault not set up; follow `references/bootstrap.md`. 200 → check its `schema_version` and migrate if older. | -| 2 | `/vault/_agent/memory/semantic/operator-preferences.md` | Jason's profile | +| 1 | `/vault/_agent/quicksilver-vault.md` | The bootstrap marker. 404 → vault not set up; follow `references/bootstrap.md`. 200 → check its `schema_version` and migrate if older. | +| 2 | `/vault/_agent/memory/semantic/operator-preferences.md` | The operator's profile | | 3 | `/vault/_agent/context/current-context.md` | Active scope + Scope History | | 4 | `/vault/_agent/sessions/` (listing) | Pick the ~5 most recent by reverse lex sort (filenames `YYYY-MM-DD-HHMM-.md`, so lex == chrono); only read the ones whose slugs look relevant | | 5 | `/vault/journal/daily/YYYY-MM-DD.md` | Today's note; 404 is fine — it's created on first agent activity | Do not read every session log — older sessions are reachable via `POST /search/simple/?query=...` when needed. -**If a specific project is in play**, follow up with a **search across all lifecycle subfolders** (`active/`, `incubating/`, `on-hold/`, `archived/`) — searching one folder at a time misses notes filed elsewhere. Search by **both the slug AND any human title** Jason used in this conversation: +**If a specific project is in play**, follow up with a **search across all lifecycle subfolders** (`active/`, `incubating/`, `on-hold/`, `archived/`) — searching one folder at a time misses notes filed elsewhere. Search by **both the slug AND any human title** the operator used in this conversation: ```bash # slug -curl -s -X POST -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/search/simple/?query=" +curl -s -X POST -H "$AUTH" "$BASE/search/simple/?query=" # human title (avoids missing notes filed under a different name) -curl -s -X POST -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/search/simple/?query=" +curl -s -X POST -H "$AUTH" "$BASE/search/simple/?query=" ``` Then read whichever match lives at `projects//.md`. @@ -89,7 +94,7 @@ When routing accepted items, send each to its proper home: - Durable fact → PUT `_agent/memory/semantic/.md` - Person fact → PUT/PATCH `resources/people/.md` -Then record the move in `inbox/processing-log/YYYY-MM-DD.md` (one line per item: `- `). Don't delete the original capture unless Jason explicitly asks — the processing log is the audit trail. +Then record the move in `inbox/processing-log/YYYY-MM-DD.md` (one line per item: `- `). Don't delete the original capture unless the operator explicitly asks — the processing log is the audit trail. ## Project Lifecycle @@ -108,31 +113,29 @@ Projects move through four folders under `projects/`. The folder name and the `s ## When to Write Memory -Write when Jason: +Write when the operator: - States a fact, preference, or commitment worth keeping ("I prefer X", "we use uv not pip", "standup is Tuesday at 10") - Makes a non-obvious decision worth recording - Says "remember that", "save this", "log this", "add to memory", "note that" - Finishes a meaningful working session future sessions should pick up -Write in third person about Jason. Every note carries the canonical frontmatter (see below). Agent-generated notes set `agent_written: true`. +Write in third person about the operator (by name). Every note carries the canonical frontmatter (see below). Agent-generated notes set `agent_written: true`. ### Before you write — search first (MANDATORY for new notes) **Before creating any new note at `projects//.md`, `_agent/memory/semantic/.md`, `resources/people/.md`, or any other slug-addressed location, search the whole vault for that slug.** Listing a single folder (e.g. `projects/active/`) is NOT sufficient — a note with the same slug may exist in `projects/on-hold/`, `projects/incubating/`, `projects/archived/`, or under a different folder entirely. ```bash -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/search/simple/?query=" +curl -s -X POST -H "$AUTH" "$BASE/search/simple/?query=" ``` If a match is found: - In a non-active project subfolder (`on-hold/`, `incubating/`, `archived/`): **promote/merge** — PUT the merged content to `projects/active/.md` with `status: active`, then DELETE the old location. Preserve the earliest `created:` date. - In the same folder you intended to write: **update in place** (PATCH or merged PUT). Never silently overwrite — fold the existing content in first. -- Elsewhere (e.g. a stale duplicate under `resources/`): tell Jason and ask which should be canonical before writing. +- Elsewhere (e.g. a stale duplicate under `resources/`): tell the operator and ask which should be canonical before writing. -**Search both the slug AND any human title** Jason used (e.g. slug `echo-memory` and title `ECHO plugin`). Slug-only searches miss notes filed under a different naming scheme. Two cheap `POST /search/simple/?query=...` calls beat one expensive cleanup pass later. +**Search both the slug AND any human title** the operator used (e.g. slug `quicksilver` and title `Quicksilver plugin`). Slug-only searches miss notes filed under a different naming scheme. Two cheap `POST /search/simple/?query=...` calls beat one expensive cleanup pass later. Only after the search comes back empty (or you've decided to merge) is it safe to create a new note. This rule prevents the most common duplication bug: a note exists in `on-hold/` but the agent only checked `active/` and created a parallel record. @@ -157,11 +160,10 @@ cat > /tmp/obs_entry.md << 'OBSEOF' - 2026-06-05: OBSEOF -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X POST -H "$AUTH" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_entry.md \ - "https://echoapi.alwisp.com/vault/inbox/captures/inbox.md" + "$BASE/vault/inbox/captures/inbox.md" ``` POST appends to the end of a file (creating it if absent). Use it for inbox captures and log sections. @@ -173,9 +175,9 @@ POST appends to the end of a file (creating it if absent). Use it for inbox capt **Default: GET the document map first** (every first PATCH to a file in a session — cache the result mentally for subsequent PATCHes to the same file). This eliminates the most common failure mode of PATCH: ```bash -curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -H "$AUTH" \ -H "Accept: application/vnd.olrapi.document-map+json" \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" + "$BASE/vault/_agent/memory/semantic/operator-preferences.md" ``` Returns `{ "headings": [...], "blocks": [...], "frontmatterFields": [...] }`. Copy the heading string verbatim into `Target`. Only skip the doc-map GET if you wrote the file yourself in this session (you already know its structure). @@ -184,17 +186,16 @@ Then PATCH: ```bash cat > /tmp/obs_patch.md << 'OBSEOF' -Jason prefers status updates that lead with the decision. + prefers status updates that lead with the decision. OBSEOF -curl -s -X PATCH \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PATCH -H "$AUTH" \ -H "Operation: append" \ -H "Target-Type: heading" \ -H "Target: Operator Preferences::Fact / Pattern" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_patch.md \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" + "$BASE/vault/_agent/memory/semantic/operator-preferences.md" ``` Use `Operation: replace` to overwrite a section entirely (e.g. a project's `Project Name::Current status`). Percent-encode non-ASCII characters in the `Target` header; spaces are fine. @@ -204,11 +205,10 @@ Use `Operation: replace` to overwrite a section entirely (e.g. a project's `Proj When a PATCH or PUT changes meaningful content (status update, decision recorded, current-status replacement, scope switch), also PATCH the frontmatter `updated:` field to today's date. This keeps stale-detection queries honest. ```bash -curl -s -X PATCH \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PATCH -H "$AUTH" \ -H "Operation: replace" -H "Target-Type: frontmatter" -H "Target: updated" \ -H "Content-Type: application/json" --data '"2026-06-06"' \ - "https://echoapi.alwisp.com/vault/projects/active/.md" + "$BASE/vault/projects/active/.md" ``` Skip the bump for **routine log appends** — adding an Agent Log line, an inbox capture, or a timestamped Observations bullet doesn't constitute a meaningful content change. Bump on substance, not on heartbeat. @@ -236,11 +236,10 @@ source_notes: [] - [[journal/daily/2026-06-05]] OBSEOF -curl -s -X PUT \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PUT -H "$AUTH" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_file.md \ - "https://echoapi.alwisp.com/vault/projects/active/my-project.md" + "$BASE/vault/projects/active/my-project.md" ``` The API creates intermediate directories automatically. @@ -248,14 +247,13 @@ The API creates intermediate directories automatically. ### Search the vault ```bash -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/search/simple/?query=your+search+terms" +curl -s -X POST -H "$AUTH" \ + "$BASE/search/simple/?query=your+search+terms" ``` ## Scope Switching (`current-context.md`) -`_agent/context/current-context.md` tracks a single active scope. Jason routinely shifts scope within a day (echo plugin → MPM brand → WISP docs). +`_agent/context/current-context.md` tracks a single active scope. The operator may shift scope several times within a day. When scope changes: @@ -290,14 +288,14 @@ After substantive activity, write a one-line entry to today's daily note's `## A 4. PATCH-append the entry under the target `::Agent Log` (the H1 of a daily note is the date, so that's the full target path). ```bash +# $BASE and $AUTH come from the local config file (see Configuration & First Run) DATE=$(date +%Y-%m-%d) -DAILY="https://echoapi.alwisp.com/vault/journal/daily/${DATE}.md" -AUTH="Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" +DAILY="$BASE/vault/journal/daily/${DATE}.md" # 1+2: ensure the daily note exists (PUT from template if missing) HTTP=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$DAILY") if [ "$HTTP" = "404" ]; then - curl -s -H "$AUTH" "https://echoapi.alwisp.com/vault/journal/templates/daily-note-template.md" \ + curl -s -H "$AUTH" "$BASE/vault/journal/templates/daily-note-template.md" \ | sed "s/{{date:YYYY-MM-DD}}/${DATE}/g" \ | curl -s -X PUT -H "$AUTH" -H "Content-Type: text/markdown" --data-binary @- "$DAILY" fi @@ -343,7 +341,7 @@ curl -s -X PATCH -H "$AUTH" \ **Decision mirrors:** if the decision belongs to an existing note in `projects/active/`, add a `[[wikilink]]` to the ADR under that project's `## Key Decisions` heading (PATCH). If no matching project note exists, skip the mirror — the by-date ADR is sufficient; do not invent topical mirror files in `decisions/by-project/`. -Never delete files unless Jason explicitly asks. Memory is append-friendly; deletion is destructive. +Never delete files unless the operator explicitly asks. Memory is append-friendly; deletion is destructive. ## Session Logging @@ -358,23 +356,22 @@ cat > /tmp/obs_session.md << 'OBSEOF' OBSEOF -curl -s -X PUT \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PUT -H "$AUTH" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_session.md \ - "https://echoapi.alwisp.com/vault/_agent/sessions/2026-06-05-1430-my-session.md" + "$BASE/vault/_agent/sessions/2026-06-05-1430-my-session.md" ``` Then add a one-line entry to today's daily note via the **Daily Note — Agent Log** procedure above. ## Vault Unreachable -If the API returns a connection error, timeout, or `502`, tell Jason once that the memory vault is unreachable (a `502` usually means Obsidian/the REST plugin is not running on the backend), then proceed without memory. Do not retry repeatedly. +If the API returns a connection error, timeout, or `502`, tell the operator once that the memory vault is unreachable (a `502` usually means Obsidian/the REST plugin is not running on the backend), then proceed without memory. Do not retry repeatedly. ## Style Rules -- Write in third person about Jason: "Jason prefers X", not "I prefer X". -- Jason is both operator and architect here — unlike goldbrain (Bryan's vault, which Jason architected). Do not cross-write: Bryan's preferences belong in goldbrain, Jason's belong here. +- Write in third person about the operator, by name: " prefers X", not "I prefer X". +- One vault, one operator. Do not cross-write into another operator's vault; this skill's configured endpoint owns this operator's memory. - **Anchor relative dates on the conversation's `currentDate`** before writing. "Today" → `currentDate`. "Thursday" / "next week" → resolve to an absolute `YYYY-MM-DD`. Never guess from training-data knowledge of the current year. - Every memory file has canonical YAML frontmatter — see `references/vault-layout.md`. - Set `agent_written: true` on agent-generated notes and list `source_notes` (plain relative paths, not links). @@ -382,15 +379,15 @@ If the API returns a connection error, timeout, or `502`, tell Jason once that t - **`source_notes` lists the note(s) that *triggered* or *supplied content for* this one** — e.g. the session log that produced a project update, or the daily note where a captured fact originated. It is a *backward* link to inputs. Forward links (this note → other notes it references) belong in the `## Related` section in the note body, never in frontmatter. - **Never put `[[wikilinks]]` in frontmatter** — YAML parses them as nested lists and the links break in Obsidian's reading view. Put all cross-references in a `## Related` section in the note **body** as a bulleted list of `[[links]]`. - Use Obsidian wiki links (`[[note name]]`) freely in the note **body** for cross-references. -- Keep entries short and focused. Fewer, sharper entries beat many noisy ones — Jason explicitly prefers concision. -- About to write something large or sensitive? Show Jason the content first and confirm. +- Keep entries short and focused. Fewer, sharper entries beat many noisy ones — default to concision. +- About to write something large or sensitive? Show the operator the content first and confirm. ## operator-preferences.md — Rules vs Observations `_agent/memory/semantic/operator-preferences.md` separates two kinds of content: -- `## Fact / Pattern` — **promoted, deduped rules.** No date prefix. These are timeless: "Jason prefers concise communication." Append here only when a rule is stable. -- `## Observations` — **timestamped raw observations.** Date-prefixed: `- 2026-06-06: Jason chose X over Y because Z.` This is where new evidence goes by default. +- `## Fact / Pattern` — **promoted, deduped rules.** No date prefix. These are timeless: " prefers concise communication." Append here only when a rule is stable. +- `## Observations` — **timestamped raw observations.** Date-prefixed: `- 2026-06-06: chose X over Y because Z.` This is where new evidence goes by default. During monthly Vault Health or when an observation stabilizes, promote it from `## Observations` into `## Fact / Pattern` (drop the date) and remove the duplicate from Observations. Trim Observations to the last ~30 entries when it grows past that — the rest live in session logs. diff --git a/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md b/quicksilver.plugin.src/skills/quicksilver/references/api-reference.md similarity index 66% rename from echo-memory.plugin.src/skills/echo-memory/references/api-reference.md rename to quicksilver.plugin.src/skills/quicksilver/references/api-reference.md index 7b77444..f4207e5 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md +++ b/quicksilver.plugin.src/skills/quicksilver/references/api-reference.md @@ -1,8 +1,17 @@ -# ECHO — Obsidian Local REST API Reference +# Quicksilver — Obsidian Local REST API Reference -Server: `https://echoapi.alwisp.com` (reverse proxy → backend Obsidian Local REST API) -Auth header: `Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab` -The endpoint has a **valid TLS certificate** — `-k` is not required. Paths address the vault at its **root**. +Server and key are **not hardcoded** — they come from the local config file +(`~/.quicksilver/quicksilver-config.json`; see `references/bootstrap.md`). Load them once +per session and use them in every call: + +```bash +BASE="" # e.g. https://obsidian.example.com +AUTH="Authorization: Bearer " +``` + +The examples below use `$BASE` and the `$AUTH` header. The endpoint is expected to present a +**valid TLS certificate** — `-k` is not required (add it only if the operator's endpoint uses a +self-signed cert). Paths address the vault at its **root**. --- @@ -10,18 +19,15 @@ The endpoint has a **valid TLS certificate** — `-k` is not required. Paths add ```bash # Read any file by vault path -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/context/current-context.md" +curl -s -H "$AUTH" "$BASE/vault/_agent/context/current-context.md" ``` Returns raw file content (text/markdown). On 404, the file does not exist. ```bash # Read a specific heading's content only -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md/heading/Operator" +curl -s -H "$AUTH" \ + "$BASE/vault/_agent/memory/semantic/operator-preferences.md/heading/Operator" ``` Nested headings: separate levels with `::` (URL-encode spaces as `%20`): @@ -35,9 +41,7 @@ Nested headings: separate levels with `::` (URL-encode spaces as `%20`): ```bash # List contents of a directory (trailing slash required) -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/sessions/" +curl -s -H "$AUTH" "$BASE/vault/_agent/sessions/" ``` Returns JSON: `{ "files": [...], "folders": [...] }`. @@ -53,11 +57,10 @@ cat > /tmp/obs_entry.md << 'OBSEOF' - 2026-06-05: your entry here OBSEOF -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X POST -H "$AUTH" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_entry.md \ - "https://echoapi.alwisp.com/vault/inbox/captures/inbox.md" + "$BASE/vault/inbox/captures/inbox.md" ``` --- @@ -84,11 +87,10 @@ source_notes: [] - [[projects/active/some-project]] OBSEOF -curl -s -X PUT \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PUT -H "$AUTH" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_file.md \ - "https://echoapi.alwisp.com/vault/_agent/sessions/2026-06-05-1430-my-session.md" + "$BASE/vault/_agent/sessions/2026-06-05-1430-my-session.md" ``` --- @@ -103,17 +105,16 @@ curl -s -X PUT \ ```bash cat > /tmp/obs_patch.md << 'OBSEOF' -Jason prefers concise status updates — lead with the decision. +The operator prefers concise status updates — lead with the decision. OBSEOF -curl -s -X PATCH \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PATCH -H "$AUTH" \ -H "Operation: append" \ -H "Target-Type: heading" \ -H "Target: Operator Preferences::Fact / Pattern" \ -H "Content-Type: text/markdown" \ --data-binary @/tmp/obs_patch.md \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" + "$BASE/vault/_agent/memory/semantic/operator-preferences.md" ``` ### Discover heading / block / frontmatter targets @@ -121,10 +122,9 @@ curl -s -X PATCH \ When unsure of the exact heading path, GET the note with the document-map Accept header: ```bash -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -H "$AUTH" \ -H "Accept: application/vnd.olrapi.document-map+json" \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" + "$BASE/vault/_agent/memory/semantic/operator-preferences.md" ``` Returns `{ "headings": [...], "blocks": [...], "frontmatterFields": [...] }`. Copy the heading string verbatim into `Target`. @@ -140,14 +140,13 @@ Same call with `Operation: prepend`. ### Patch a frontmatter field ```bash -curl -s -X PATCH \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +curl -s -X PATCH -H "$AUTH" \ -H "Operation: replace" \ -H "Target-Type: frontmatter" \ -H "Target: updated" \ -H "Content-Type: application/json" \ --data '"2026-06-05"' \ - "https://echoapi.alwisp.com/vault/projects/active/vault-foundation.md" + "$BASE/vault/projects/active/vault-foundation.md" ``` --- @@ -155,9 +154,8 @@ curl -s -X PATCH \ ## Searching ```bash -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/search/simple/?query=weekly+review" +curl -s -X POST -H "$AUTH" \ + "$BASE/search/simple/?query=weekly+review" ``` Returns an array of `{ filename, score, matches: [{ context, match }] }`. @@ -167,9 +165,8 @@ Returns an array of `{ filename, score, matches: [{ context, match }] }`. ## Deleting Files ```bash -curl -s -X DELETE \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/archive/notes/old-note.md" +curl -s -X DELETE -H "$AUTH" \ + "$BASE/vault/archive/notes/old-note.md" ``` Only on explicit operator request. Deletion is destructive. @@ -203,6 +200,6 @@ Only on explicit operator request. Deletion is destructive. | Concept / reference note | `resources/concepts/` or `resources/references/` | PUT | | Daily activity / Agent Log | `journal/daily/YYYY-MM-DD.md` | POST / PATCH | | Periodic review | `reviews/{weekly,monthly,quarterly,annual}/` | PUT | -| Bootstrap marker (plugin-owned) | `_agent/echo-vault.md` (`schema_version`, bootstrap date) — the "is this vault set up?" probe | GET / PUT | +| Bootstrap marker (plugin-owned) | `_agent/quicksilver-vault.md` (`schema_version`, bootstrap date, operator) — the "is this vault set up?" probe | GET / PUT | **Slug rules:** kebab-case, ASCII, ~40 chars max. Every file carries canonical frontmatter (see `vault-layout.md`). diff --git a/echo-memory.plugin.src/skills/echo-memory/references/bootstrap.md b/quicksilver.plugin.src/skills/quicksilver/references/bootstrap.md similarity index 54% rename from echo-memory.plugin.src/skills/echo-memory/references/bootstrap.md rename to quicksilver.plugin.src/skills/quicksilver/references/bootstrap.md index f5487c5..461a23c 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/bootstrap.md +++ b/quicksilver.plugin.src/skills/quicksilver/references/bootstrap.md @@ -1,22 +1,83 @@ -# Bootstrap & Repair +# First-run, Bootstrap & Repair -The **plugin is the single source of truth** for ECHO's structure. Everything needed to stand up a vault ships in this skill under `scaffold/` — there is no dependency on any in-vault control doc and no external/local re-seed path. This makes the vault portable: point the REST API at any empty Obsidian vault, run this procedure, and it becomes a working ECHO vault. +The **plugin is the single source of truth** for Quicksilver's structure. Everything needed to stand up a vault ships in this skill under `scaffold/` — there is no dependency on any in-vault control doc and no external/local re-seed path. This makes the vault portable: point the REST API at any empty Obsidian vault, run this procedure, and it becomes a working Quicksilver vault. -The vault holds **data only**. It carries no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` / `index.md`. The "is this vault set up?" signal is a small marker file, `_agent/echo-vault.md`. +The vault holds **data only**. It carries no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` / `index.md`. The "is this vault set up?" signal is a small marker file, `_agent/quicksilver-vault.md`. + +There are **two layers** of setup, probed in order: + +1. **Local config** — is *this install* configured with an endpoint + key? (Step 0 below.) +2. **Vault marker** — is the *vault* that endpoint points at scaffolded? (the Probe + Fresh bootstrap below.) + +--- + +## Step 0 — Client configuration (first run) + +Credentials live in a **local config file**, never in the plugin source and never in the vault: ``` -AUTH="Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" -BASE="https://echoapi.alwisp.com" +~/.quicksilver/quicksilver-config.json (macOS/Linux) +%USERPROFILE%\.quicksilver\quicksilver-config.json (Windows) +``` + +At session start, **read this file** (use the Read tool — no `jq` needed). Its shape: + +```json +{ + "schema": 1, + "endpoint": "https://obsidian.example.com", + "api_key": "", + "operator": { "name": "Alex Rivera", "role": "Network Engineer" }, + "configured_at": "YYYY-MM-DD", + "verified_at": "YYYY-MM-DD" +} +``` + +- **File present →** load `endpoint` (use as `$BASE`), `api_key` (use as the bearer), and `operator`. Proceed to the vault-marker probe below. No prompts. +- **File absent → FRESH INSTALL.** Tell the operator this looks like a first run, then prompt for: + 1. **API endpoint FQDN** (e.g. `https://obsidian.example.com`) + 2. **API key** (the Local REST API bearer token) + 3. **Operator name + role** (used to personalize memory) + + Verify the endpoint before saving — probe the marker path: + + ```bash + BASE="https://obsidian.example.com" # from the operator + AUTH="Authorization: Bearer " + curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$BASE/vault/_agent/quicksilver-vault.md" + ``` + + - `200` or `404` → reachable and authorized (`404` just means the vault isn't bootstrapped yet — expected on a brand-new vault). Write the config file. + - connection error / `401` / `403` → tell the operator what failed and re-prompt. Do **not** write the config file. + + On success, write the config file with the Write tool (set permissions to `0600` where the platform supports it), stamping `configured_at` / `verified_at` with today's date (from `currentDate`): + + ```json + { + "schema": 1, + "endpoint": "https://obsidian.example.com", + "api_key": "", + "operator": { "name": "Alex Rivera", "role": "Network Engineer" }, + "configured_at": "{{DATE}}", + "verified_at": "{{DATE}}" + } + ``` + +From here on, every call in this skill uses `$BASE` (the configured endpoint) and an `$AUTH` header built from `api_key`: + +```bash +BASE="" +AUTH="Authorization: Bearer " ``` --- ## Probe — is the vault bootstrapped? -At session start, GET the marker: +With `$BASE` / `$AUTH` set, GET the marker: ```bash -curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$BASE/vault/_agent/echo-vault.md" +curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$BASE/vault/_agent/quicksilver-vault.md" ``` - **200** → bootstrapped. Read the marker's `schema_version`; if it is **less than** the plugin's current schema (1), run a migration pass (see *Migrations* below), otherwise proceed straight to the loading procedure in `SKILL.md`. @@ -54,7 +115,7 @@ _agent/outputs/briefs _agent/outputs/drafts _agent/outputs/summaries _agent/o A leaf README is just a one-liner, e.g.: ```bash -printf '# %s\n\nMemory vault folder. See the echo-memory plugin for conventions.\n' "captures" \ +printf '# %s\n\nMemory vault folder. See the quicksilver plugin for conventions.\n' "captures" \ | curl -s -X PUT -H "$AUTH" -H "Content-Type: text/markdown" --data-binary @- \ "$BASE/vault/inbox/captures/README.md" ``` @@ -84,7 +145,7 @@ curl -s -X PUT -H "$AUTH" -H "Content-Type: text/markdown" \ ### 3. Anchor seeds (only if absent — no fabricated facts) -Substitute `{{DATE}}` → today, then PUT each: +Substitute `{{DATE}}` → today, and in the operator-preferences seed substitute `{{OPERATOR}}` / `{{ROLE}}` → the name and role captured in Step 0. Then PUT each: | Scaffold file | Vault path | |---|---| @@ -92,7 +153,7 @@ Substitute `{{DATE}}` → today, then PUT each: | `scaffold/anchors/current-context.seed.md` | `_agent/context/current-context.md` | | `scaffold/anchors/inbox.seed.md` | `inbox/captures/inbox.md` | -The operator-preferences seed is deliberately empty — **do not invent preferences.** Real facts accrue through use. +Beyond the name/role captured at first run, the operator-preferences seed is deliberately empty — **do not invent preferences.** Real facts accrue through use. ### 4. Vault README (human signpost) @@ -100,7 +161,7 @@ Substitute `{{DATE}}` if present, then PUT `scaffold/README.vault.md` → `/vaul ### 5. Marker (write last) -Substitute `{{DATE}}`, then PUT `scaffold/echo-vault.md` → `/vault/_agent/echo-vault.md`. Once this returns `200`, the vault is bootstrapped. +Substitute `{{DATE}}` and `{{OPERATOR}}` (the operator's name from Step 0), then PUT `scaffold/quicksilver-vault.md` → `/vault/_agent/quicksilver-vault.md`. The marker records schema version, bootstrap date, and operator name only — **never the key.** Once this returns `200`, the vault is bootstrapped. ### 6. First-run trace @@ -118,4 +179,15 @@ Run the same steps 1–5, but GET-probe each path first and **only create what i When the marker's `schema_version` is older than the plugin's, apply the migration steps for each intervening version, then PATCH the marker's `schema_version` frontmatter to the new value. -- **0 → 1** (control-docs-in-plugin): the vault previously carried root control docs (`CLAUDE.md`, `BOOTSTRAP.md`, `STRUCTURE.md`, `index.md`). Back them up outside the vault, DELETE them, PUT the thin `scaffold/README.vault.md` over the old verbose `README.md`, write the `_agent/echo-vault.md` marker, and scrub now-dangling `[[CLAUDE]]`/`[[BOOTSTRAP]]`/`[[STRUCTURE]]`/`[[index]]` links from the `## Related` sections of `operator-preferences.md` and `current-context.md` (leave historical session logs alone). Confirm with the operator before deleting. +- **0 → 1** (control-docs-in-plugin): the vault previously carried root control docs (`CLAUDE.md`, `BOOTSTRAP.md`, `STRUCTURE.md`, `index.md`). Back them up outside the vault, DELETE them, PUT the thin `scaffold/README.vault.md` over the old verbose `README.md`, write the marker, and scrub now-dangling `[[CLAUDE]]`/`[[BOOTSTRAP]]`/`[[STRUCTURE]]`/`[[index]]` links from the `## Related` sections of `operator-preferences.md` and `current-context.md` (leave historical session logs alone). Confirm with the operator before deleting. + +### Marker rename (legacy `echo-vault.md` → `quicksilver-vault.md`) + +A vault bootstrapped by the older `echo-memory` plugin has its marker at `_agent/echo-vault.md`. On probe, if `_agent/quicksilver-vault.md` is `404` **but** `_agent/echo-vault.md` is `200`, treat it as a rename migration rather than a fresh bootstrap: + +1. GET `_agent/echo-vault.md`, preserve its `schema_version` / `bootstrapped` / `operator` values. +2. PUT the current `scaffold/quicksilver-vault.md` to `_agent/quicksilver-vault.md` with those values carried over. +3. DELETE `_agent/echo-vault.md`. +4. Scrub any dangling `[[echo-vault]]` links from `## Related` sections (leave historical session logs alone). + +Confirm with the operator before deleting the old marker. diff --git a/echo-memory.plugin.src/skills/echo-memory/references/operating-contract.md b/quicksilver.plugin.src/skills/quicksilver/references/operating-contract.md similarity index 85% rename from echo-memory.plugin.src/skills/echo-memory/references/operating-contract.md rename to quicksilver.plugin.src/skills/quicksilver/references/operating-contract.md index 7cfef3a..f2a1960 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/operating-contract.md +++ b/quicksilver.plugin.src/skills/quicksilver/references/operating-contract.md @@ -1,6 +1,6 @@ -# ECHO — Operating Contract +# Quicksilver — Operating Contract -The durable, client-independent contract for any agent operating against the ECHO vault. These principles and safety rules formerly lived in the vault's `CLAUDE.md`; they now live in the plugin so they survive regardless of what is (or isn't) in the vault. Day-to-day *procedure* — loading order, search-first, triage, scope switching, PATCH/append rules — is owned by `SKILL.md`. This file holds the things that don't change between sessions or clients. +The durable, client-independent contract for any agent operating against the Quicksilver vault. These principles and safety rules formerly lived in the vault's `CLAUDE.md`; they now live in the plugin so they survive regardless of what is (or isn't) in the vault. Day-to-day *procedure* — loading order, search-first, triage, scope switching, PATCH/append rules — is owned by `SKILL.md`. This file holds the things that don't change between sessions or clients. ## What this agent is diff --git a/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md b/quicksilver.plugin.src/skills/quicksilver/references/session-log-template.md similarity index 83% rename from echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md rename to quicksilver.plugin.src/skills/quicksilver/references/session-log-template.md index 1592c1f..bf4a4aa 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md +++ b/quicksilver.plugin.src/skills/quicksilver/references/session-log-template.md @@ -5,7 +5,7 @@ Session logs go in: `_agent/sessions/YYYY-MM-DD-HHMM-.md` **Filename format is canonical and not optional.** The four-digit local-time HHMM component is what makes session filenames lex-sort in true chronological order — the loading procedure depends on it. Before PUT-ing a new session log, validate the filename matches `^\d{4}-\d{2}-\d{2}-\d{4}-[a-z0-9-]+\.md$`. Legacy session logs without HHMM exist in the vault; do not edit their names, but every new write must use the full form. The slug describes what the session was about in 2–5 words, kebab-case. -Examples: `2026-06-05-1430-echo-plugin-build.md`, `2026-05-14-0900-q1-review-prep.md`. +Examples: `2026-06-05-1430-quicksilver-plugin-build.md`, `2026-05-14-0900-q1-review-prep.md`. Keep logs focused. Capture the goal, what was read/done, decisions, outputs, open threads, and the next step. This matches the vault's `_agent/templates/session-log-template.md`. @@ -77,21 +77,21 @@ client: claude-code # Session Log ## Goal -Build and package the echo-memory CoWork plugin against the live vault. +Build and package the quicksilver CoWork plugin against the live vault. ## Notes Read -- [[BOOTSTRAP]], [[STRUCTURE]], [[_agent/memory/semantic/operator-preferences]] +- [[_agent/memory/semantic/operator-preferences]] ## Actions Taken Verified the REST API end-to-end, confirmed the scaffold copied into the live vault, -created missing empty folders, and built the plugin (SKILL + 4 reference files). +created missing empty folders, and built the plugin (SKILL + reference files). ## Decisions Made -- Vault addressed at root — ECHO is a dedicated vault. -- Key hardcoded in the plugin (not in the vault) — personal plugin, per the reference pattern. +- Vault addressed at root — Quicksilver is a dedicated vault. +- Credentials read from the local config file (`~/.quicksilver/quicksilver-config.json`); the API key is never stored in the vault. ## Outputs Created -- `echo-memory.plugin` — installable CoWork plugin +- `quicksilver.plugin` — installable CoWork plugin ## Open Threads - [ ] Validate Claude Code direct filesystem access to the vault host. diff --git a/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md b/quicksilver.plugin.src/skills/quicksilver/references/vault-layout.md similarity index 84% rename from echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md rename to quicksilver.plugin.src/skills/quicksilver/references/vault-layout.md index f741a01..0460fa1 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md +++ b/quicksilver.plugin.src/skills/quicksilver/references/vault-layout.md @@ -1,6 +1,6 @@ # Vault Layout & Frontmatter Conventions -**This document is canonical.** The ECHO vault holds data only — there are no `CLAUDE.md` / `STRUCTURE.md` / `BOOTSTRAP.md` / `index.md` control docs in it. Layout, taxonomy, and frontmatter conventions live here in the plugin; the bootstrap procedure (`references/bootstrap.md`) builds the tree below into any empty vault. +**This document is canonical.** The Quicksilver vault holds data only — there are no `CLAUDE.md` / `STRUCTURE.md` / `BOOTSTRAP.md` / `index.md` control docs in it. Layout, taxonomy, and frontmatter conventions live here in the plugin; the bootstrap procedure (`references/bootstrap.md`) builds the tree below into any empty vault. ## Folder Map (root-addressed) @@ -33,7 +33,7 @@ ├── reviews/ ← weekly / monthly / quarterly / annual ├── archive/ ← notes / projects / imports └── _agent/ - ├── echo-vault.md ← bootstrap marker: schema_version + bootstrap date (plugin-owned; the "is this vault set up?" probe) + ├── quicksilver-vault.md ← bootstrap marker: schema_version + bootstrap date (plugin-owned; the "is this vault set up?" probe) ├── context/ ← current-context.md and task bundles ├── memory/ │ ├── working/ ← transient, time-boxed @@ -100,14 +100,14 @@ not rewrite frontmatter — the append goes after existing content. To change The profile analog. Canonical headings: -- `## Operator` — who Jason is (one paragraph) +- `## Operator` — who the operator is (one paragraph), captured at first run - `## Fact / Pattern` — **promoted, deduped rules.** No date prefix. Timeless. - `## Observations` — **timestamped raw observations.** Date-prefixed lines (`- 2026-06-06: ...`). Default landing zone for new evidence. - `## Evidence` — citations/links supporting the rules - `## Recommendation or Implication` — how the rules should shape behavior - `## Review Notes` — confidence / last review date -Append observed facts under `## Observations` by default. Promote to `## Fact / Pattern` (dropping the date) once a pattern stabilizes. "The operator" is Jason — he is both operator and architect of this vault. +Append observed facts under `## Observations` by default. Promote to `## Fact / Pattern` (dropping the date) once a pattern stabilizes. The operator's name is captured at first run (stored in the local config file and the vault marker's `operator:` field); write memory in third person using that name. ### projects/active/\.md @@ -142,7 +142,7 @@ One paragraph, kept fresh via PATCH replace. ### sessions/YYYY-MM-DD-HHMM-\.md -See `session-log-template.md`. ECHO uses an **HHMM time component** in the filename — this is **canonical, not optional**. The four-digit local-time component makes filenames lex-sort in true chronological order, which the loading procedure relies on. Older session logs without HHMM exist; leave them alone, but every new one must use the full `YYYY-MM-DD-HHMM-.md` form. +See `session-log-template.md`. Quicksilver uses an **HHMM time component** in the filename — this is **canonical, not optional**. The four-digit local-time component makes filenames lex-sort in true chronological order, which the loading procedure relies on. Older session logs without HHMM exist; leave them alone, but every new one must use the full `YYYY-MM-DD-HHMM-.md` form. ### decisions/by-date/YYYY-MM-DD-\.md @@ -150,7 +150,7 @@ ADR-style: Context → Decision → Consequences. If the decision belongs to an ### people/\.md -`type: person`. Use lowercase kebab-case for the slug (e.g. `jason-stedwell.md`). +`type: person`. Use lowercase kebab-case for the slug (e.g. `alex-rivera.md`). --- diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/README.vault.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/README.vault.md similarity index 71% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/README.vault.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/README.vault.md index 4714e4a..2f63152 100644 --- a/echo-memory.plugin.src/skills/echo-memory/scaffold/README.vault.md +++ b/quicksilver.plugin.src/skills/quicksilver/scaffold/README.vault.md @@ -1,12 +1,12 @@ -# ECHO Memory Vault +# Quicksilver Memory Vault This Obsidian vault is the persistent memory substrate ("second brain") for its operator. It is read and written across Claude / CoWork sessions through the Obsidian Local REST API. -**This vault holds data, not logic.** All operating procedure — how the vault is bootstrapped, how notes are routed, the taxonomy, frontmatter conventions, and safety rules — lives in the **`echo-memory` plugin**, which is the single source of truth. There are intentionally no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` control docs in this vault; updating or porting ECHO means updating or installing the plugin, not editing files here. +**This vault holds data, not logic.** All operating procedure — how the vault is bootstrapped, how notes are routed, the taxonomy, frontmatter conventions, and safety rules — lives in the **`quicksilver` plugin**, which is the single source of truth. There are intentionally no `CLAUDE.md` / `BOOTSTRAP.md` / `STRUCTURE.md` control docs in this vault; updating or porting Quicksilver means updating or installing the plugin, not editing files here. - **Layout:** see the plugin's `references/vault-layout.md`. - **Operating contract & safety:** see the plugin's `references/operating-contract.md`. - **Bootstrap / repair:** see the plugin's `references/bootstrap.md`. -- **Version marker:** `_agent/echo-vault.md` records the schema version and bootstrap date. +- **Version marker:** `_agent/quicksilver-vault.md` records the schema version and bootstrap date. Folders: `inbox/`, `journal/`, `projects/`, `areas/`, `resources/`, `decisions/`, `reviews/`, `archive/`, and the agent subtree `_agent/`. diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/current-context.seed.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/current-context.seed.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/current-context.seed.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/current-context.seed.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/inbox.seed.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/inbox.seed.md similarity index 77% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/inbox.seed.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/inbox.seed.md index df919f1..ffbe2a7 100644 --- a/echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/inbox.seed.md +++ b/quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/inbox.seed.md @@ -1,3 +1,3 @@ # Inbox — Captures -Quick captures land here as date-prefixed lines (`- {{DATE}}: `), one per line, via POST. Triage routes durable items to their proper home (see the echo-memory skill's Inbox Triage). Don't delete originals on triage — the processing log is the audit trail. +Quick captures land here as date-prefixed lines (`- {{DATE}}: `), one per line, via POST. Triage routes durable items to their proper home (see the quicksilver skill's Inbox Triage). Don't delete originals on triage — the processing log is the audit trail. diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/operator-preferences.seed.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/operator-preferences.seed.md similarity index 80% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/operator-preferences.seed.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/operator-preferences.seed.md index cde04d4..9741744 100644 --- a/echo-memory.plugin.src/skills/echo-memory/scaffold/anchors/operator-preferences.seed.md +++ b/quicksilver.plugin.src/skills/quicksilver/scaffold/anchors/operator-preferences.seed.md @@ -13,7 +13,8 @@ last_reviewed: {{DATE}} # Operator Preferences ## Operator - +{{OPERATOR}} — {{ROLE}}. + ## Fact / Pattern diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/echo-vault.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/quicksilver-vault.md similarity index 58% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/echo-vault.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/quicksilver-vault.md index e83b49f..a5c92f2 100644 --- a/echo-memory.plugin.src/skills/echo-memory/scaffold/echo-vault.md +++ b/quicksilver.plugin.src/skills/quicksilver/scaffold/quicksilver-vault.md @@ -8,12 +8,15 @@ agent_written: true source_notes: [] schema_version: 1 bootstrapped: {{DATE}} -managed_by: echo-memory-plugin +managed_by: quicksilver-plugin +operator: {{OPERATOR}} --- -# ECHO Vault Marker +# Quicksilver Vault Marker -This file marks the vault as bootstrapped by the **echo-memory plugin** and records its schema version. The plugin's loading procedure GETs this file as its "is this vault set up?" probe; a `404` triggers a fresh bootstrap. +This file marks the vault as bootstrapped by the **quicksilver plugin** and records its schema version. The plugin's loading procedure GETs this file as its "is this vault set up?" probe; a `404` triggers a fresh bootstrap. - `schema_version` — bumped by the plugin when the vault layout changes; a mismatch is the hook for a migration pass (see `references/bootstrap.md`). +- `operator` — the vault owner's name, captured at first run. Non-secret identity only. +- **No secret is ever stored here.** The API endpoint and key live in the local config file (`~/.quicksilver/quicksilver-config.json`), never in the vault. - Do not hand-edit. The plugin owns this file. diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/context-bundle-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/context-bundle-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/context-bundle-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/context-bundle-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/semantic-memory-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/semantic-memory-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/semantic-memory-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/semantic-memory-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/session-log-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/session-log-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/session-log-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/session-log-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/working-memory-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/working-memory-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/_agent/templates/working-memory-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/_agent/templates/working-memory-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/decisions/decision-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/decisions/decision-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/decisions/decision-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/decisions/decision-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/journal/templates/daily-note-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/journal/templates/daily-note-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/journal/templates/daily-note-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/journal/templates/daily-note-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/journal/templates/weekly-review-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/journal/templates/weekly-review-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/journal/templates/weekly-review-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/journal/templates/weekly-review-template.md diff --git a/echo-memory.plugin.src/skills/echo-memory/scaffold/templates/projects/project-template.md b/quicksilver.plugin.src/skills/quicksilver/scaffold/templates/projects/project-template.md similarity index 100% rename from echo-memory.plugin.src/skills/echo-memory/scaffold/templates/projects/project-template.md rename to quicksilver.plugin.src/skills/quicksilver/scaffold/templates/projects/project-template.md