3f69682b1c
## What Adds `/cognee-remember` to the SDK's Slack app and brings the two commands' replies in line with the cloud integration. `/cognee-remember` fell through to *"Command `/cognee-remember` is not yet supported."* — remembering was reachable only through the **Remember this** message shortcut. That shortcut covers what Slack already has on screen; it cannot cover what Slack never saw, which is most of what's worth keeping: a decision from a call, a conclusion someone records after the fact. ## Changes **New `/cognee-remember <text>`** (`handle_cognee_remember.py`) - Writes to the same dataset and `node_set` as the shortcut, so both land as one Slack-origin body of memory rather than two the graph can't relate. - Acks inside Slack's 3-second window and saves detached, confirming via `response_url`. `cognee.remember` resolves — and on a first save, creates — the dataset before returning even with `run_in_background=True`, so it can't run inline. - Refuses an unconnected workspace and an unlinked member *before* writing: a note landing in the installer's memory because the author never linked is worse than one refused with a reason. - Every reply is ephemeral, matching `/cognee-ask` — what someone commits to memory isn't the app's to announce. **Fixed the not-linked reply** `handle_cognee_ask.py` and `handle_slack_interactive.py` both told people to run `` `/cognee-link <api_key>` `` and create a key from their API Keys settings. That argument has never existed and the SDK flow uses no key — leftover from before linking became a magic link. The wording now lives in `handle_slack_link.py` beside the command it names, so the three call sites can't drift again. **Empty-input replies now carry an example** instead of `Usage: ...`, and acks match cloud's `🔎 Recalling:` / `💾 Remembering:`. **Manifest** gains the command, plus a note that adding a slash command to an existing app requires reinstalling it — Slack doesn't grant new commands to an existing install. ## Unrelated fix, folded in because it blocks verifying any of the above `GET /datasets/{id}/data` raises `TypeError: dict() got multiple values for keyword argument 'dataset_id'`. `Data` carries its own `dataset_id` column now, so `dict(**jsonable_encoder(data), dataset_id=…)` collides with the encoded row on every call. **Every dataset detail view 500s — on `dev`, not just here.** A dict literal resolves the duplicate instead of raising; the requested id still wins, which matters because the column is nullable. Happy to split this out if you'd rather it land on its own. ## Testing 205 unit tests pass (was 197). New coverage for `/cognee-remember`: unconnected workspace, unlinked member, empty text, the ack/detached-save split, save failure reporting back rather than raising, and ack truncation not touching the stored note. Manually verified end to end against a real Slack workspace over ngrok. ## Note No `/cognee-forget`. cognee can delete a dataset, one item, or everything — not by description. A command taking a description of a fact couldn't honour it, and someone believing otherwise is the worst outcome available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- ## Follow-up commit: the manifest that actually gets installed `scripts/slack-app-manifest.sdk.yml` — the manifest people install from when testing the SDK locally — still listed only `/cognee-ask` and `/cognee-link`. Adding the command to the tracked `slack-app-manifest.yml` was not enough: an app created from the SDK manifest can't invoke `/cognee-remember` at all, because Slack refuses an unregistered command client-side and nothing ever reaches the backend. It looks exactly like a broken server. This cost a full debugging session to find, which is the argument against keeping two manifests for one app. Worth deciding as part of this PR: 1. **Delete `scripts/slack-app-manifest.sdk.yml`** and drive local testing off the tracked manifest with a host substitution — one source of truth, drift impossible. 2. **Keep both** and add a test asserting the two files declare identical `slash_commands`, so CI catches the next divergence. I've committed the fix plus a note about the reinstall requirement, but haven't picked between those — happy to do either. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>