[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-mem0-mem0-test-integration":3,"mdc--yjy1rx-key":49,"related-org-mem0-mem0-test-integration":2384,"related-repo-mem0-mem0-test-integration":2528},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":44,"sourceUrl":47,"mdContent":48},"mem0-test-integration","verify Mem0 integration tests","Verify a Mem0 integration produced by \u002Fmem0-integrate. Runs in the same workspace on the same branch (loose coupling) — installs dependencies, runs the repo's native test suite, then exercises a real end-to-end smoke flow against the user's API key. Produces a scorecard. TRIGGER when: user has just run \u002Fmem0-integrate and says \"verify\", \"test the integration\", \"run \u002Fmem0-test-integration\", or when a .mem0-integration\u002F directory exists and tests have not been run yet on the current branch. DO NOT TRIGGER when: the user wants to run general project tests (defer to the repo's native test command), or when no prior \u002Fmem0-integrate run exists in the current branch (ask them to run \u002Fmem0-integrate first). This skill ONLY catches compile and runtime bugs by design. Logical integration errors — wrong data stored, wrong time retrieved, wrong user scoping — are on the human reviewer.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"mem0","Mem0","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmem0.png","mem0ai",[13,17,20,23],{"name":14,"slug":15,"type":16},"QA","qa","tag",{"name":18,"slug":19,"type":16},"Memory","memory",{"name":21,"slug":22,"type":16},"Agents","agents",{"name":24,"slug":25,"type":16},"Testing","testing",60691,"https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0","2026-07-13T06:12:50.669701","Apache-2.0",7066,[22,32,33,34,35,36,37,38,39,19,40,41,42,43],"ai","ai-agents","application","chatbots","chatgpt","genai","llm","long-term-memory","memory-management","python","rag","state-management",{"repoUrl":27,"stars":26,"forks":30,"topics":45,"description":46},[22,32,33,34,35,36,37,38,39,19,40,41,42,43],"Universal memory layer for AI Agents","https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\u002Ftree\u002FHEAD\u002Fskills\u002Fmem0-test-integration","---\nname: mem0-test-integration\ndescription: >\n  Verify a Mem0 integration produced by \u002Fmem0-integrate. Runs in the same\n  workspace on the same branch (loose coupling) — installs dependencies,\n  runs the repo's native test suite, then exercises a real end-to-end\n  smoke flow against the user's API key. Produces a scorecard.\n  TRIGGER when: user has just run \u002Fmem0-integrate and says \"verify\",\n  \"test the integration\", \"run \u002Fmem0-test-integration\", or when a\n  .mem0-integration\u002F directory exists and tests have not been run yet\n  on the current branch.\n  DO NOT TRIGGER when: the user wants to run general project tests\n  (defer to the repo's native test command), or when no prior \u002Fmem0-integrate\n  run exists in the current branch (ask them to run \u002Fmem0-integrate first).\n  This skill ONLY catches compile and runtime bugs by design. Logical\n  integration errors — wrong data stored, wrong time retrieved, wrong\n  user scoping — are on the human reviewer.\nlicense: Apache-2.0\nmetadata:\n  author: mem0ai\n  version: \"0.1.0\"\n  category: ai-memory\n  tags: \"memory, integration, testing, tdd, platform, oss\"\n  coupling: loose\n  mem0_tested_versions: \"mem0ai (PyPI) >=2.0.0,\u003C3.0.0; mem0ai (npm) >=3.0.0,\u003C4.0.0\"\n---\n\n# mem0-test-integration\n\nVerifies what `\u002Fmem0-integrate` produced. Runs in the same workspace,\non the same feature branch. Loose coupling — fast, catches compile and\nruntime bugs, does not catch logical errors.\n\n## Canonical sources (use these, not ambient knowledge)\n\nAll static checks and smoke-test shapes validate against these URLs.\n`WebFetch` each before running step 3.\n\n- Scope-tagged docs index: https:\u002F\u002Fdocs.mem0.ai\u002Fllms.txt\n- OpenAPI (Platform REST): https:\u002F\u002Fdocs.mem0.ai\u002Fopenapi.json\n- Published SDK skill (canonical call patterns): https:\u002F\u002Fraw.githubusercontent.com\u002Fmem0ai\u002Fmem0\u002Fmain\u002Fskills\u002Fmem0\u002FSKILL.md\n- Vercel AI SDK skill (if the target repo uses `@ai-sdk\u002F*`): https:\u002F\u002Fraw.githubusercontent.com\u002Fmem0ai\u002Fmem0\u002Fmain\u002Fskills\u002Fmem0-vercel-ai-sdk\u002FSKILL.md\n- SDK source (cross-check version against frontmatter `mem0_tested_versions`):\n  - Repo root: https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\n  - Python: https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\u002Ftree\u002Fmain\u002Fmem0\n  - TypeScript: https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\u002Ftree\u002Fmain\u002Fmem0-ts\n\nRead the `Delegated skill:` field in `.mem0-integration\u002Fplan.md` — if it\nnames a skill URL, fetch that skill and use its example blocks as the\nreference for both static checks (step 3) and the smoke test (step 5).\n\n## Non-invasiveness contract\n\nEvery check in this skill assumes the integration is **additive and\nfeature-flagged** (see `\u002Fmem0-integrate` \"Integration principles\").\nSpecifically:\n\n- `product.json` must contain a `feature_flag` field.\n- Steps 4–6 run in two passes:\n  - **Pass A — flag unset.** All pre-existing tests must pass, smoke\u002FE2E\n    skip. The repo must behave like `main`. Any failure here is a\n    **hard fail** — do not let the self-heal loop attempt a patch.\n  - **Pass B — flag set.** New tests must pass, smoke and E2E run.\n- If Pass A fails, the scorecard marks `non_invasive: false` and sets\n  `overall: fail` with a distinct reason code the integrator's heal\n  loop refuses to touch.\n\n## Preconditions\n\nRefuse to start unless ALL of the following are true:\n\n- `.mem0-integration\u002F` directory exists in the repo root.\n- `.mem0-integration\u002Fproduct.json`, `goal.md`, and `plan.md` are readable\n  and internally consistent (JSON parses, docs non-empty).\n- Current branch name begins with `mem0-integrate\u002F` (set by the companion\n  skill). Prevents accidental runs on unrelated branches.\n- Working tree is clean. The skill never modifies source files; any dirty\n  state means the integration is mid-edit and not ready to verify.\n- The same API key the integration used is available in the environment\n  (`MEM0_API_KEY` for Platform, `OPENAI_API_KEY` for OSS — read which from\n  `product.json`). Interactive mode asks if missing; CI mode exits 2.\n\nExit with a written rationale on any precondition failure. Never attempt\nto \"fix up\" state.\n\n## Pipeline\n\n### 1. Read the contract\n\nLoad:\n\n- `product.json` → which language, which product (Platform vs OSS), which\n  mem0 version, `write_site`, `read_site`.\n- `plan.md` → the mechanical contract (write pattern, read pattern,\n  preserved behavior).\n- `goal.md` → the intent (displayed in the scorecard only; not tested).\n\n### 2. Install dependencies\n\nRoute by language from `product.json`:\n\n| Language | Command |\n|---|---|\n| Python | `pip install -e .` if editable, else `pip install -r requirements.txt`. Then `pip install mem0ai` if not already present at the pinned version. |\n| TypeScript \u002F JavaScript | `npm install` (or `pnpm install` \u002F `yarn install` if detected by lockfile). |\n\nIf install fails → exit code 2 with stderr tail. Never move to testing\nif dependencies don't resolve.\n\n### 3. Static sanity checks (fast, local, no API calls)\n\n- **Import check**: does the write-site file import the expected Mem0\n  surface? Authoritative list comes from `## Identify the User's Setup`\n  in `https:\u002F\u002Fdocs.mem0.ai\u002Fllms.txt`:\n  - Platform Python → `from mem0 import MemoryClient`\n  - Platform TS → `import MemoryClient from \"mem0ai\"`\n  - OSS Python → `from mem0 import Memory`\n  - OSS TS → `import { Memory } from \"mem0ai\u002Foss\"`\n\n  If `plan.md` names a delegated skill (e.g., Vercel AI), use *that*\n  skill's import signature instead of the list above. Mismatch → fail\n  with line number.\n- **Version check**: installed `mem0ai` version falls in the range from\n  this skill's `mem0_tested_versions`. Out of range → warn but continue.\n- **Type check** (TS tracks only): run `tsc --noEmit` or `tsup --dts`.\n  Non-zero → fail.\n- **Lint** (if the repo has a linter configured): run the repo's own\n  lint command. Lint failures from this skill's changes → fail; pre-existing\n  lint failures → surface as a warning.\n- **Eager-init check**: grep the `write_site` and `read_site` files (paths\n  from `product.json`) for `MemoryClient(` or `Memory(` at module scope —\n  i.e., not inside a function, method, or class body. `MemoryClient()`\n  validates the API key in `__init__` (network call) and OSS `Memory()`\n  can eagerly initialize embedding\u002FLLM providers — module-level\n  instantiation hits the wire on import and breaks Pass A's test\n  collection whenever the key is unset. Hit → fail with `file:line` and\n  the lazy-init guidance from `\u002Fmem0-integrate` step 8 constraint #7.\n\n### 4. Run the repo's native test suite (two passes)\n\n| Language | Test command (in priority order) |\n|---|---|\n| Python | `pytest` with the test files from step 5 of the companion skill, else `python -m unittest discover`. |\n| TypeScript \u002F JavaScript | `npm test` if defined in package.json; else auto-detect `vitest` or `jest`. |\n\n**Pass A — `feature_flag` unset.** Run the *entire* pre-existing suite\n(excluding the new `test_mem0_*` files). **Must be 100% green.** Any\nfailure here marks `non_invasive: false` in the scorecard and is\na **hard fail** — the integrator's self-heal loop refuses to touch it.\n\n**Pass B — `feature_flag` set** (value from `product.json`). Run the\nfull suite including the new tests. All must pass.\n\nIsolate integration-introduced failures using `git diff main..HEAD\n--name-only`. A test file that exists on `main` and fails only under\nthe integration branch (flag set *or* unset) counts against the\nscorecard regardless of pass. A test file that already failed on `main`\nis surfaced as `pre_existing_unrelated` and does not count — but is\nstill reported so the user can clean it up.\n\nCapture output to `.mem0-integration\u002Ftest-stdout-flag-off.log` and\n`.mem0-integration\u002Ftest-stdout-flag-on.log`. Scorecard reports pass\u002Ffail\nper pass.\n\n### 5. Smoke test (real API call, shortest round-trip)\n\nScripted end-to-end flow tailored to `product.json`. The call shapes\nbelow are the minimal ones; if `plan.md` names a delegated skill, use\n*that skill's* minimal example verbatim instead — it is the canonical\nshape for the detected stack.\n\n**Platform (Python):**\n\n    from mem0 import MemoryClient\n    c = MemoryClient()                               # uses MEM0_API_KEY\n    uid = f\"mem0-test-integration-{os.urandom(4).hex()}\"\n    c.add([{\"role\": \"user\", \"content\": \"I prefer aisle seats\"}], user_id=uid)\n    hits = c.search(\"seat preference\", user_id=uid)\n    assert any(\"aisle\" in h.get(\"memory\", \"\") for h in hits), hits\n    c.delete_all(user_id=uid)                        # clean up\n\n**Platform (TS):** same shape with `MemoryClient` from `\"mem0ai\"`.\n\n**OSS (Python \u002F TS):** uses `Memory()` \u002F `new Memory()` with default config\n(OpenAI LLM via `OPENAI_API_KEY`, local Qdrant). If the repo ships a\n`docker-compose.yml` with a Qdrant service, the skill starts it first and\ntears it down after. If no backing store is reachable → fail with a\nclear message naming the fix.\n\nThe smoke test always uses a **disposable random user_id** prefixed with\n`mem0-test-integration-` so a failed cleanup doesn't pollute the user's\nreal data. A background tidy step deletes any prefix-matching entries\nolder than 24 hours on the next run.\n\nCapture output to `.mem0-integration\u002Fsmoke-stdout.log`.\n\n### 6. E2E integration test (run the app, exercise the flow)\n\nUnit tests + smoke prove the SDK works in isolation. This step is the\nreal signal: **does memory actually appear in the app's user-visible\noutput when the integration runs end-to-end?**\n\nRequires `plan.md` to contain an `E2E recipe:` section (authored by\n`\u002Fmem0-integrate` step 5). If absent → status `skipped` (not `fail`),\nnote in scorecard that the repo has no runnable entry point.\n\nRecipe fields the skill reads:\n\n- `start` — shell command to launch the app using `$PORT` for any network\n  port. Run in background with stdout\u002Fstderr teed to\n  `.mem0-integration\u002Fe2e-app.log`.\n- `ready_probe` — how to detect readiness. `url=... status=...` polls an\n  HTTP endpoint; `log=\"...\"` waits for a substring in `e2e-app.log`;\n  `sleep=N` waits N seconds (last resort). 60-second hard timeout.\n- `compose_services` — optional. If set, bring them up via\n  `docker compose up -d \u003Cservices>` before `start`, tear them down with\n  `docker compose down` at the end.\n- `write_call` — triggers the Mem0 write path exactly once. Output is\n  captured and surfaced on failure. 60-second hard timeout.\n- `write_async_wait_ms` — pause after `write_call` to let async memory\n  flushes land. Default 0.\n- `read_call` — triggers the Mem0 read path. Typically a fresh session\n  or new request that should surface the stored memory.\n- `read_assert` — substring, `regex=...`, or `jsonpath=\u003Cexpr>=\u003Cvalue>`\n  that must appear in `read_call`'s stdout. This is the E2E pass gate.\n\nExecution order:\n\n1. Allocate an ephemeral TCP port; export as `PORT`.\n2. Set `MEM0_USER_ID` to a disposable `mem0-test-integration-\u003Crand>` value\n   and export it, so the app can use the same scoping the smoke test does\n   if the recipe wants cleanup.\n3. Bring up `compose_services` if named.\n4. Run `start` in the background.\n5. Poll `ready_probe` until success or 60s timeout. Timeout → fail.\n6. Run `write_call`. Non-zero exit → fail (but continue to cleanup).\n7. Sleep `write_async_wait_ms`.\n8. Run `read_call`.\n9. Evaluate `read_assert` against `read_call`'s stdout. Miss → fail.\n10. Cleanup (always, even on failure): SIGTERM the app, SIGKILL after\n    5s, `docker compose down` if services were started, `delete_all`\n    memories matching `mem0-test-integration-*` on Platform scenarios.\n\nOn any failure, the scorecard includes:\n\n- Last 40 lines of `e2e-app.log`\n- Full `write_call` output\n- Full `read_call` output\n- The expected vs actual for `read_assert`\n\n### 7. Scorecard\n\nWrite `.mem0-integration\u002Fscorecard.md` and `.mem0-integration\u002Fscorecard.json`:\n\n    {\n      \"timestamp\": \"2026-04-20T14:03:11Z\",\n      \"branch\": \"mem0-integrate\u002Fremember-user-preferences\",\n      \"product\": \"platform\",\n      \"language\": \"python\",\n      \"mem0_version\": \"2.0.0\",\n      \"non_invasive\": true,\n      \"feature_flag\": \"MEM0_ENABLED\",\n      \"results\": {\n        \"install\":      {\"status\": \"pass\", \"duration_ms\": 12043},\n        \"static_checks\":{\"status\": \"pass\", \"duration_ms\": 812},\n        \"unit_tests_flag_off\": {\"status\": \"pass\", \"duration_ms\": 3920, \"count\": 47,\n                                \"reason\": \"all pre-existing tests green with flag unset\"},\n        \"unit_tests_flag_on\":  {\"status\": \"pass\", \"duration_ms\": 4321, \"count\": 49},\n        \"smoke_test\":   {\"status\": \"pass\", \"duration_ms\": 2890, \"memory_id\": \"mem_...\"},\n        \"e2e_test\":     {\"status\": \"pass\", \"duration_ms\": 14200,\n                         \"ready_probe_ms\": 3100, \"write_exit\": 0,\n                         \"read_assert_matched\": true}\n      },\n      \"friction\": {\n        \"dependency_install_retries\": 0,\n        \"pre_existing_test_failures\": 0,\n        \"warnings\": [\"mem0ai 2.0.0 pinned; consider 2.0.1 for fix X\"]\n      },\n      \"overall\": \"pass\"\n    }\n\nThe markdown version is human-readable and includes:\n\n- Goal doc + plan doc reprinted at top (so reviewers don't have to hunt).\n- Each check with pass\u002Ffail + log excerpt.\n- Friction summary.\n- Verbatim warnings from mem0 SDK (if any — e.g., deprecated field usage).\n- **Explicit \"NOT checked\" section** listing what loose coupling misses:\n  \"Whether the stored data is what the user wants stored. Whether search\n  runs at the right moment. Whether user_id matches the actual session\n  scope. Human review required.\"\n\n### 8. Report + exit\n\n- Print the scorecard path + overall pass\u002Ffail to stdout.\n- **Do not commit the scorecard files.** They live in `.mem0-integration\u002F`,\n  which is gitignored. The user can inspect and optionally pin.\n- On fail: print the first failing step's log tail (last 40 lines) and\n  stop. Do not attempt to fix anything.\n\n## Artifacts (all under `.mem0-integration\u002F`)\n\n| File | Purpose | Retention |\n|---|---|---|\n| `scorecard.md` | Human-readable verdict. | Overwritten per run. |\n| `scorecard.json` | Machine-readable verdict. Consumed by the CI scorecard workflow later. | Overwritten per run. |\n| `test-stdout-flag-off.log` | Step 4 Pass A (pre-existing suite, flag unset). | Overwritten per run. |\n| `test-stdout-flag-on.log` | Step 4 Pass B (full suite, flag set). | Overwritten per run. |\n| `smoke-stdout.log` | Full output from step 5. | Overwritten per run. |\n| `e2e-app.log` | Background app stdout\u002Fstderr from step 6. | Overwritten per run. |\n| `e2e-calls.log` | write_call + read_call invocations and outputs. | Overwritten per run. |\n\n## Modes\n\n| Mode | Trigger | Behavior |\n|---|---|---|\n| Interactive (default) | TTY present, `MEM0_TEST_CI` unset | Asks for missing keys, prints friendly summaries. |\n| CI | `MEM0_TEST_CI=1` | Keys must be in env, no prompts, non-zero exit on any fail. JSON scorecard goes to stdout's tail for workflow parsing. |\n\n## Invocation\n\n    \u002Fmem0-test-integration                       # interactive, all steps\n    \u002Fmem0-test-integration --ci                  # non-interactive\n    \u002Fmem0-test-integration --skip-smoke          # no API calls, no E2E\n    \u002Fmem0-test-integration --skip-e2e            # unit + smoke only (faster CI)\n    \u002Fmem0-test-integration --only-smoke          # just smoke\n    \u002Fmem0-test-integration --only-e2e            # just E2E (assumes deps installed)\n\nComposition: `--skip-*` can stack (`--skip-smoke --skip-e2e` = static +\nunit only, zero API cost). `--only-*` is mutually exclusive with all\nother flags.\n\n## Exit codes\n\n| Code | Meaning |\n|---|---|\n| 0 | All checks passed. |\n| 1 | Precondition failed (no `.mem0-integration\u002F`, wrong branch, dirty tree). |\n| 2 | Missing env key (CI mode) or dependency install failure. |\n| 3 | Static sanity check failed (wrong import, type error). |\n| 4 | Unit tests failed (Pass B — integration itself broken). |\n| 5 | Smoke test failed. |\n| 6 | E2E test failed (ready_probe timeout, write\u002Fread call failed, or read_assert miss). |\n| 7 | Non-invasiveness violation: Pass A failed (pre-existing tests broke). Integrator's heal loop refuses to touch this. |\n| 8 | Internal error (skill bug — report it). |\n\n## Explicitly out of scope\n\n- **Modifying source files.** The skill is read-only against the repo.\n  If verification exposes a bug, re-run `\u002Fmem0-integrate` on the same\n  goal + plan; do not hand-patch.\n- **Fixing broken tests.** Failing unit tests are a signal that the\n  integration is wrong, not that the tests are wrong. The skill does\n  not \"try a different test.\"\n- **Deep logical correctness.** The E2E step proves \"something the user\n  said earlier comes back later,\" which is a useful but shallow signal.\n  It does NOT prove the integration picks the *right* facts to store,\n  scopes `user_id` correctly across real users, or handles conflict\n  resolution well. That's human review territory.\n- **Self-healing.** This skill never modifies source files. The paired\n  `\u002Fmem0-integrate` skill in its default `--heal` mode consumes the\n  scorecard produced here and drives its own remediation loop. Exit\n  code 7 (non-invasiveness violation) is the explicit signal the heal\n  loop must stop and surface to the user.\n- **Cross-branch comparisons.** No `main` baseline diffing. The\n  scorecard reflects this branch only.\n- **Running against production data.** Every smoke test uses a disposable\n  random user_id and cleans up after. Never touches any other user's data.\n",{"data":50,"body":57},{"name":4,"description":6,"license":29,"metadata":51},{"author":11,"version":52,"category":53,"tags":54,"coupling":55,"mem0_tested_versions":56},"0.1.0","ai-memory","memory, integration, testing, tdd, platform, oss","loose","mem0ai (PyPI) >=2.0.0,\u003C3.0.0; mem0ai (npm) >=3.0.0,\u003C4.0.0",{"type":58,"children":59},"root",[60,67,82,89,102,209,230,236,256,342,348,353,440,445,451,458,463,511,517,529,627,632,638,878,884,962,1014,1038,1080,1101,1107,1133,1141,1153,1178,1217,1237,1248,1254,1264,1307,1312,1492,1497,1649,1654,1699,1705,1724,1733,1738,1771,1777,1807,1820,1994,2000,2075,2081,2090,2119,2125,2271,2277],{"type":61,"tag":62,"props":63,"children":64},"element","h1",{"id":4},[65],{"type":66,"value":4},"text",{"type":61,"tag":68,"props":69,"children":70},"p",{},[71,73,80],{"type":66,"value":72},"Verifies what ",{"type":61,"tag":74,"props":75,"children":77},"code",{"className":76},[],[78],{"type":66,"value":79},"\u002Fmem0-integrate",{"type":66,"value":81}," produced. Runs in the same workspace,\non the same feature branch. Loose coupling — fast, catches compile and\nruntime bugs, does not catch logical errors.",{"type":61,"tag":83,"props":84,"children":86},"h2",{"id":85},"canonical-sources-use-these-not-ambient-knowledge",[87],{"type":66,"value":88},"Canonical sources (use these, not ambient knowledge)",{"type":61,"tag":68,"props":90,"children":91},{},[92,94,100],{"type":66,"value":93},"All static checks and smoke-test shapes validate against these URLs.\n",{"type":61,"tag":74,"props":95,"children":97},{"className":96},[],[98],{"type":66,"value":99},"WebFetch",{"type":66,"value":101}," each before running step 3.",{"type":61,"tag":103,"props":104,"children":105},"ul",{},[106,120,131,142,161],{"type":61,"tag":107,"props":108,"children":109},"li",{},[110,112],{"type":66,"value":111},"Scope-tagged docs index: ",{"type":61,"tag":113,"props":114,"children":118},"a",{"href":115,"rel":116},"https:\u002F\u002Fdocs.mem0.ai\u002Fllms.txt",[117],"nofollow",[119],{"type":66,"value":115},{"type":61,"tag":107,"props":121,"children":122},{},[123,125],{"type":66,"value":124},"OpenAPI (Platform REST): ",{"type":61,"tag":113,"props":126,"children":129},{"href":127,"rel":128},"https:\u002F\u002Fdocs.mem0.ai\u002Fopenapi.json",[117],[130],{"type":66,"value":127},{"type":61,"tag":107,"props":132,"children":133},{},[134,136],{"type":66,"value":135},"Published SDK skill (canonical call patterns): ",{"type":61,"tag":113,"props":137,"children":140},{"href":138,"rel":139},"https:\u002F\u002Fraw.githubusercontent.com\u002Fmem0ai\u002Fmem0\u002Fmain\u002Fskills\u002Fmem0\u002FSKILL.md",[117],[141],{"type":66,"value":138},{"type":61,"tag":107,"props":143,"children":144},{},[145,147,153,155],{"type":66,"value":146},"Vercel AI SDK skill (if the target repo uses ",{"type":61,"tag":74,"props":148,"children":150},{"className":149},[],[151],{"type":66,"value":152},"@ai-sdk\u002F*",{"type":66,"value":154},"): ",{"type":61,"tag":113,"props":156,"children":159},{"href":157,"rel":158},"https:\u002F\u002Fraw.githubusercontent.com\u002Fmem0ai\u002Fmem0\u002Fmain\u002Fskills\u002Fmem0-vercel-ai-sdk\u002FSKILL.md",[117],[160],{"type":66,"value":157},{"type":61,"tag":107,"props":162,"children":163},{},[164,166,172,174],{"type":66,"value":165},"SDK source (cross-check version against frontmatter ",{"type":61,"tag":74,"props":167,"children":169},{"className":168},[],[170],{"type":66,"value":171},"mem0_tested_versions",{"type":66,"value":173},"):\n",{"type":61,"tag":103,"props":175,"children":176},{},[177,187,198],{"type":61,"tag":107,"props":178,"children":179},{},[180,182],{"type":66,"value":181},"Repo root: ",{"type":61,"tag":113,"props":183,"children":185},{"href":27,"rel":184},[117],[186],{"type":66,"value":27},{"type":61,"tag":107,"props":188,"children":189},{},[190,192],{"type":66,"value":191},"Python: ",{"type":61,"tag":113,"props":193,"children":196},{"href":194,"rel":195},"https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\u002Ftree\u002Fmain\u002Fmem0",[117],[197],{"type":66,"value":194},{"type":61,"tag":107,"props":199,"children":200},{},[201,203],{"type":66,"value":202},"TypeScript: ",{"type":61,"tag":113,"props":204,"children":207},{"href":205,"rel":206},"https:\u002F\u002Fgithub.com\u002Fmem0ai\u002Fmem0\u002Ftree\u002Fmain\u002Fmem0-ts",[117],[208],{"type":66,"value":205},{"type":61,"tag":68,"props":210,"children":211},{},[212,214,220,222,228],{"type":66,"value":213},"Read the ",{"type":61,"tag":74,"props":215,"children":217},{"className":216},[],[218],{"type":66,"value":219},"Delegated skill:",{"type":66,"value":221}," field in ",{"type":61,"tag":74,"props":223,"children":225},{"className":224},[],[226],{"type":66,"value":227},".mem0-integration\u002Fplan.md",{"type":66,"value":229}," — if it\nnames a skill URL, fetch that skill and use its example blocks as the\nreference for both static checks (step 3) and the smoke test (step 5).",{"type":61,"tag":83,"props":231,"children":233},{"id":232},"non-invasiveness-contract",[234],{"type":66,"value":235},"Non-invasiveness contract",{"type":61,"tag":68,"props":237,"children":238},{},[239,241,247,249,254],{"type":66,"value":240},"Every check in this skill assumes the integration is ",{"type":61,"tag":242,"props":243,"children":244},"strong",{},[245],{"type":66,"value":246},"additive and\nfeature-flagged",{"type":66,"value":248}," (see ",{"type":61,"tag":74,"props":250,"children":252},{"className":251},[],[253],{"type":66,"value":79},{"type":66,"value":255}," \"Integration principles\").\nSpecifically:",{"type":61,"tag":103,"props":257,"children":258},{},[259,278,321],{"type":61,"tag":107,"props":260,"children":261},{},[262,268,270,276],{"type":61,"tag":74,"props":263,"children":265},{"className":264},[],[266],{"type":66,"value":267},"product.json",{"type":66,"value":269}," must contain a ",{"type":61,"tag":74,"props":271,"children":273},{"className":272},[],[274],{"type":66,"value":275},"feature_flag",{"type":66,"value":277}," field.",{"type":61,"tag":107,"props":279,"children":280},{},[281,283],{"type":66,"value":282},"Steps 4–6 run in two passes:\n",{"type":61,"tag":103,"props":284,"children":285},{},[286,311],{"type":61,"tag":107,"props":287,"children":288},{},[289,294,296,302,304,309],{"type":61,"tag":242,"props":290,"children":291},{},[292],{"type":66,"value":293},"Pass A — flag unset.",{"type":66,"value":295}," All pre-existing tests must pass, smoke\u002FE2E\nskip. The repo must behave like ",{"type":61,"tag":74,"props":297,"children":299},{"className":298},[],[300],{"type":66,"value":301},"main",{"type":66,"value":303},". Any failure here is a\n",{"type":61,"tag":242,"props":305,"children":306},{},[307],{"type":66,"value":308},"hard fail",{"type":66,"value":310}," — do not let the self-heal loop attempt a patch.",{"type":61,"tag":107,"props":312,"children":313},{},[314,319],{"type":61,"tag":242,"props":315,"children":316},{},[317],{"type":66,"value":318},"Pass B — flag set.",{"type":66,"value":320}," New tests must pass, smoke and E2E run.",{"type":61,"tag":107,"props":322,"children":323},{},[324,326,332,334,340],{"type":66,"value":325},"If Pass A fails, the scorecard marks ",{"type":61,"tag":74,"props":327,"children":329},{"className":328},[],[330],{"type":66,"value":331},"non_invasive: false",{"type":66,"value":333}," and sets\n",{"type":61,"tag":74,"props":335,"children":337},{"className":336},[],[338],{"type":66,"value":339},"overall: fail",{"type":66,"value":341}," with a distinct reason code the integrator's heal\nloop refuses to touch.",{"type":61,"tag":83,"props":343,"children":345},{"id":344},"preconditions",[346],{"type":66,"value":347},"Preconditions",{"type":61,"tag":68,"props":349,"children":350},{},[351],{"type":66,"value":352},"Refuse to start unless ALL of the following are true:",{"type":61,"tag":103,"props":354,"children":355},{},[356,367,394,407,412],{"type":61,"tag":107,"props":357,"children":358},{},[359,365],{"type":61,"tag":74,"props":360,"children":362},{"className":361},[],[363],{"type":66,"value":364},".mem0-integration\u002F",{"type":66,"value":366}," directory exists in the repo root.",{"type":61,"tag":107,"props":368,"children":369},{},[370,376,378,384,386,392],{"type":61,"tag":74,"props":371,"children":373},{"className":372},[],[374],{"type":66,"value":375},".mem0-integration\u002Fproduct.json",{"type":66,"value":377},", ",{"type":61,"tag":74,"props":379,"children":381},{"className":380},[],[382],{"type":66,"value":383},"goal.md",{"type":66,"value":385},", and ",{"type":61,"tag":74,"props":387,"children":389},{"className":388},[],[390],{"type":66,"value":391},"plan.md",{"type":66,"value":393}," are readable\nand internally consistent (JSON parses, docs non-empty).",{"type":61,"tag":107,"props":395,"children":396},{},[397,399,405],{"type":66,"value":398},"Current branch name begins with ",{"type":61,"tag":74,"props":400,"children":402},{"className":401},[],[403],{"type":66,"value":404},"mem0-integrate\u002F",{"type":66,"value":406}," (set by the companion\nskill). Prevents accidental runs on unrelated branches.",{"type":61,"tag":107,"props":408,"children":409},{},[410],{"type":66,"value":411},"Working tree is clean. The skill never modifies source files; any dirty\nstate means the integration is mid-edit and not ready to verify.",{"type":61,"tag":107,"props":413,"children":414},{},[415,417,423,425,431,433,438],{"type":66,"value":416},"The same API key the integration used is available in the environment\n(",{"type":61,"tag":74,"props":418,"children":420},{"className":419},[],[421],{"type":66,"value":422},"MEM0_API_KEY",{"type":66,"value":424}," for Platform, ",{"type":61,"tag":74,"props":426,"children":428},{"className":427},[],[429],{"type":66,"value":430},"OPENAI_API_KEY",{"type":66,"value":432}," for OSS — read which from\n",{"type":61,"tag":74,"props":434,"children":436},{"className":435},[],[437],{"type":66,"value":267},{"type":66,"value":439},"). Interactive mode asks if missing; CI mode exits 2.",{"type":61,"tag":68,"props":441,"children":442},{},[443],{"type":66,"value":444},"Exit with a written rationale on any precondition failure. Never attempt\nto \"fix up\" state.",{"type":61,"tag":83,"props":446,"children":448},{"id":447},"pipeline",[449],{"type":66,"value":450},"Pipeline",{"type":61,"tag":452,"props":453,"children":455},"h3",{"id":454},"_1-read-the-contract",[456],{"type":66,"value":457},"1. Read the contract",{"type":61,"tag":68,"props":459,"children":460},{},[461],{"type":66,"value":462},"Load:",{"type":61,"tag":103,"props":464,"children":465},{},[466,491,501],{"type":61,"tag":107,"props":467,"children":468},{},[469,474,476,482,483,489],{"type":61,"tag":74,"props":470,"children":472},{"className":471},[],[473],{"type":66,"value":267},{"type":66,"value":475}," → which language, which product (Platform vs OSS), which\nmem0 version, ",{"type":61,"tag":74,"props":477,"children":479},{"className":478},[],[480],{"type":66,"value":481},"write_site",{"type":66,"value":377},{"type":61,"tag":74,"props":484,"children":486},{"className":485},[],[487],{"type":66,"value":488},"read_site",{"type":66,"value":490},".",{"type":61,"tag":107,"props":492,"children":493},{},[494,499],{"type":61,"tag":74,"props":495,"children":497},{"className":496},[],[498],{"type":66,"value":391},{"type":66,"value":500}," → the mechanical contract (write pattern, read pattern,\npreserved behavior).",{"type":61,"tag":107,"props":502,"children":503},{},[504,509],{"type":61,"tag":74,"props":505,"children":507},{"className":506},[],[508],{"type":66,"value":383},{"type":66,"value":510}," → the intent (displayed in the scorecard only; not tested).",{"type":61,"tag":452,"props":512,"children":514},{"id":513},"_2-install-dependencies",[515],{"type":66,"value":516},"2. Install dependencies",{"type":61,"tag":68,"props":518,"children":519},{},[520,522,527],{"type":66,"value":521},"Route by language from ",{"type":61,"tag":74,"props":523,"children":525},{"className":524},[],[526],{"type":66,"value":267},{"type":66,"value":528},":",{"type":61,"tag":530,"props":531,"children":532},"table",{},[533,552],{"type":61,"tag":534,"props":535,"children":536},"thead",{},[537],{"type":61,"tag":538,"props":539,"children":540},"tr",{},[541,547],{"type":61,"tag":542,"props":543,"children":544},"th",{},[545],{"type":66,"value":546},"Language",{"type":61,"tag":542,"props":548,"children":549},{},[550],{"type":66,"value":551},"Command",{"type":61,"tag":553,"props":554,"children":555},"tbody",{},[556,592],{"type":61,"tag":538,"props":557,"children":558},{},[559,565],{"type":61,"tag":560,"props":561,"children":562},"td",{},[563],{"type":66,"value":564},"Python",{"type":61,"tag":560,"props":566,"children":567},{},[568,574,576,582,584,590],{"type":61,"tag":74,"props":569,"children":571},{"className":570},[],[572],{"type":66,"value":573},"pip install -e .",{"type":66,"value":575}," if editable, else ",{"type":61,"tag":74,"props":577,"children":579},{"className":578},[],[580],{"type":66,"value":581},"pip install -r requirements.txt",{"type":66,"value":583},". Then ",{"type":61,"tag":74,"props":585,"children":587},{"className":586},[],[588],{"type":66,"value":589},"pip install mem0ai",{"type":66,"value":591}," if not already present at the pinned version.",{"type":61,"tag":538,"props":593,"children":594},{},[595,600],{"type":61,"tag":560,"props":596,"children":597},{},[598],{"type":66,"value":599},"TypeScript \u002F JavaScript",{"type":61,"tag":560,"props":601,"children":602},{},[603,609,611,617,619,625],{"type":61,"tag":74,"props":604,"children":606},{"className":605},[],[607],{"type":66,"value":608},"npm install",{"type":66,"value":610}," (or ",{"type":61,"tag":74,"props":612,"children":614},{"className":613},[],[615],{"type":66,"value":616},"pnpm install",{"type":66,"value":618}," \u002F ",{"type":61,"tag":74,"props":620,"children":622},{"className":621},[],[623],{"type":66,"value":624},"yarn install",{"type":66,"value":626}," if detected by lockfile).",{"type":61,"tag":68,"props":628,"children":629},{},[630],{"type":66,"value":631},"If install fails → exit code 2 with stderr tail. Never move to testing\nif dependencies don't resolve.",{"type":61,"tag":452,"props":633,"children":635},{"id":634},"_3-static-sanity-checks-fast-local-no-api-calls",[636],{"type":66,"value":637},"3. Static sanity checks (fast, local, no API calls)",{"type":61,"tag":103,"props":639,"children":640},{},[641,733,757,783,793],{"type":61,"tag":107,"props":642,"children":643},{},[644,649,651,657,659,664,665,712,716,718,723,725,731],{"type":61,"tag":242,"props":645,"children":646},{},[647],{"type":66,"value":648},"Import check",{"type":66,"value":650},": does the write-site file import the expected Mem0\nsurface? Authoritative list comes from ",{"type":61,"tag":74,"props":652,"children":654},{"className":653},[],[655],{"type":66,"value":656},"## Identify the User's Setup",{"type":66,"value":658},"\nin ",{"type":61,"tag":74,"props":660,"children":662},{"className":661},[],[663],{"type":66,"value":115},{"type":66,"value":528},{"type":61,"tag":103,"props":666,"children":667},{},[668,679,690,701],{"type":61,"tag":107,"props":669,"children":670},{},[671,673],{"type":66,"value":672},"Platform Python → ",{"type":61,"tag":74,"props":674,"children":676},{"className":675},[],[677],{"type":66,"value":678},"from mem0 import MemoryClient",{"type":61,"tag":107,"props":680,"children":681},{},[682,684],{"type":66,"value":683},"Platform TS → ",{"type":61,"tag":74,"props":685,"children":687},{"className":686},[],[688],{"type":66,"value":689},"import MemoryClient from \"mem0ai\"",{"type":61,"tag":107,"props":691,"children":692},{},[693,695],{"type":66,"value":694},"OSS Python → ",{"type":61,"tag":74,"props":696,"children":698},{"className":697},[],[699],{"type":66,"value":700},"from mem0 import Memory",{"type":61,"tag":107,"props":702,"children":703},{},[704,706],{"type":66,"value":705},"OSS TS → ",{"type":61,"tag":74,"props":707,"children":709},{"className":708},[],[710],{"type":66,"value":711},"import { Memory } from \"mem0ai\u002Foss\"",{"type":61,"tag":713,"props":714,"children":715},"br",{},[],{"type":66,"value":717},"If ",{"type":61,"tag":74,"props":719,"children":721},{"className":720},[],[722],{"type":66,"value":391},{"type":66,"value":724}," names a delegated skill (e.g., Vercel AI), use ",{"type":61,"tag":726,"props":727,"children":728},"em",{},[729],{"type":66,"value":730},"that",{"type":66,"value":732},"\nskill's import signature instead of the list above. Mismatch → fail\nwith line number.",{"type":61,"tag":107,"props":734,"children":735},{},[736,741,743,748,750,755],{"type":61,"tag":242,"props":737,"children":738},{},[739],{"type":66,"value":740},"Version check",{"type":66,"value":742},": installed ",{"type":61,"tag":74,"props":744,"children":746},{"className":745},[],[747],{"type":66,"value":11},{"type":66,"value":749}," version falls in the range from\nthis skill's ",{"type":61,"tag":74,"props":751,"children":753},{"className":752},[],[754],{"type":66,"value":171},{"type":66,"value":756},". Out of range → warn but continue.",{"type":61,"tag":107,"props":758,"children":759},{},[760,765,767,773,775,781],{"type":61,"tag":242,"props":761,"children":762},{},[763],{"type":66,"value":764},"Type check",{"type":66,"value":766}," (TS tracks only): run ",{"type":61,"tag":74,"props":768,"children":770},{"className":769},[],[771],{"type":66,"value":772},"tsc --noEmit",{"type":66,"value":774}," or ",{"type":61,"tag":74,"props":776,"children":778},{"className":777},[],[779],{"type":66,"value":780},"tsup --dts",{"type":66,"value":782},".\nNon-zero → fail.",{"type":61,"tag":107,"props":784,"children":785},{},[786,791],{"type":61,"tag":242,"props":787,"children":788},{},[789],{"type":66,"value":790},"Lint",{"type":66,"value":792}," (if the repo has a linter configured): run the repo's own\nlint command. Lint failures from this skill's changes → fail; pre-existing\nlint failures → surface as a warning.",{"type":61,"tag":107,"props":794,"children":795},{},[796,801,803,808,810,815,817,822,824,830,831,837,839,845,847,853,855,861,863,869,871,876],{"type":61,"tag":242,"props":797,"children":798},{},[799],{"type":66,"value":800},"Eager-init check",{"type":66,"value":802},": grep the ",{"type":61,"tag":74,"props":804,"children":806},{"className":805},[],[807],{"type":66,"value":481},{"type":66,"value":809}," and ",{"type":61,"tag":74,"props":811,"children":813},{"className":812},[],[814],{"type":66,"value":488},{"type":66,"value":816}," files (paths\nfrom ",{"type":61,"tag":74,"props":818,"children":820},{"className":819},[],[821],{"type":66,"value":267},{"type":66,"value":823},") for ",{"type":61,"tag":74,"props":825,"children":827},{"className":826},[],[828],{"type":66,"value":829},"MemoryClient(",{"type":66,"value":774},{"type":61,"tag":74,"props":832,"children":834},{"className":833},[],[835],{"type":66,"value":836},"Memory(",{"type":66,"value":838}," at module scope —\ni.e., not inside a function, method, or class body. ",{"type":61,"tag":74,"props":840,"children":842},{"className":841},[],[843],{"type":66,"value":844},"MemoryClient()",{"type":66,"value":846},"\nvalidates the API key in ",{"type":61,"tag":74,"props":848,"children":850},{"className":849},[],[851],{"type":66,"value":852},"__init__",{"type":66,"value":854}," (network call) and OSS ",{"type":61,"tag":74,"props":856,"children":858},{"className":857},[],[859],{"type":66,"value":860},"Memory()",{"type":66,"value":862},"\ncan eagerly initialize embedding\u002FLLM providers — module-level\ninstantiation hits the wire on import and breaks Pass A's test\ncollection whenever the key is unset. Hit → fail with ",{"type":61,"tag":74,"props":864,"children":866},{"className":865},[],[867],{"type":66,"value":868},"file:line",{"type":66,"value":870}," and\nthe lazy-init guidance from ",{"type":61,"tag":74,"props":872,"children":874},{"className":873},[],[875],{"type":66,"value":79},{"type":66,"value":877}," step 8 constraint #7.",{"type":61,"tag":452,"props":879,"children":881},{"id":880},"_4-run-the-repos-native-test-suite-two-passes",[882],{"type":66,"value":883},"4. Run the repo's native test suite (two passes)",{"type":61,"tag":530,"props":885,"children":886},{},[887,902],{"type":61,"tag":534,"props":888,"children":889},{},[890],{"type":61,"tag":538,"props":891,"children":892},{},[893,897],{"type":61,"tag":542,"props":894,"children":895},{},[896],{"type":66,"value":546},{"type":61,"tag":542,"props":898,"children":899},{},[900],{"type":66,"value":901},"Test command (in priority order)",{"type":61,"tag":553,"props":903,"children":904},{},[905,930],{"type":61,"tag":538,"props":906,"children":907},{},[908,912],{"type":61,"tag":560,"props":909,"children":910},{},[911],{"type":66,"value":564},{"type":61,"tag":560,"props":913,"children":914},{},[915,921,923,929],{"type":61,"tag":74,"props":916,"children":918},{"className":917},[],[919],{"type":66,"value":920},"pytest",{"type":66,"value":922}," with the test files from step 5 of the companion skill, else ",{"type":61,"tag":74,"props":924,"children":926},{"className":925},[],[927],{"type":66,"value":928},"python -m unittest discover",{"type":66,"value":490},{"type":61,"tag":538,"props":931,"children":932},{},[933,937],{"type":61,"tag":560,"props":934,"children":935},{},[936],{"type":66,"value":599},{"type":61,"tag":560,"props":938,"children":939},{},[940,946,948,954,955,961],{"type":61,"tag":74,"props":941,"children":943},{"className":942},[],[944],{"type":66,"value":945},"npm test",{"type":66,"value":947}," if defined in package.json; else auto-detect ",{"type":61,"tag":74,"props":949,"children":951},{"className":950},[],[952],{"type":66,"value":953},"vitest",{"type":66,"value":774},{"type":61,"tag":74,"props":956,"children":958},{"className":957},[],[959],{"type":66,"value":960},"jest",{"type":66,"value":490},{"type":61,"tag":68,"props":963,"children":964},{},[965,977,979,984,986,992,994,999,1001,1006,1008,1012],{"type":61,"tag":242,"props":966,"children":967},{},[968,970,975],{"type":66,"value":969},"Pass A — ",{"type":61,"tag":74,"props":971,"children":973},{"className":972},[],[974],{"type":66,"value":275},{"type":66,"value":976}," unset.",{"type":66,"value":978}," Run the ",{"type":61,"tag":726,"props":980,"children":981},{},[982],{"type":66,"value":983},"entire",{"type":66,"value":985}," pre-existing suite\n(excluding the new ",{"type":61,"tag":74,"props":987,"children":989},{"className":988},[],[990],{"type":66,"value":991},"test_mem0_*",{"type":66,"value":993}," files). ",{"type":61,"tag":242,"props":995,"children":996},{},[997],{"type":66,"value":998},"Must be 100% green.",{"type":66,"value":1000}," Any\nfailure here marks ",{"type":61,"tag":74,"props":1002,"children":1004},{"className":1003},[],[1005],{"type":66,"value":331},{"type":66,"value":1007}," in the scorecard and is\na ",{"type":61,"tag":242,"props":1009,"children":1010},{},[1011],{"type":66,"value":308},{"type":66,"value":1013}," — the integrator's self-heal loop refuses to touch it.",{"type":61,"tag":68,"props":1015,"children":1016},{},[1017,1029,1031,1036],{"type":61,"tag":242,"props":1018,"children":1019},{},[1020,1022,1027],{"type":66,"value":1021},"Pass B — ",{"type":61,"tag":74,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":66,"value":275},{"type":66,"value":1028}," set",{"type":66,"value":1030}," (value from ",{"type":61,"tag":74,"props":1032,"children":1034},{"className":1033},[],[1035],{"type":66,"value":267},{"type":66,"value":1037},"). Run the\nfull suite including the new tests. All must pass.",{"type":61,"tag":68,"props":1039,"children":1040},{},[1041,1043,1049,1051,1056,1058,1063,1065,1070,1072,1078],{"type":66,"value":1042},"Isolate integration-introduced failures using ",{"type":61,"tag":74,"props":1044,"children":1046},{"className":1045},[],[1047],{"type":66,"value":1048},"git diff main..HEAD --name-only",{"type":66,"value":1050},". A test file that exists on ",{"type":61,"tag":74,"props":1052,"children":1054},{"className":1053},[],[1055],{"type":66,"value":301},{"type":66,"value":1057}," and fails only under\nthe integration branch (flag set ",{"type":61,"tag":726,"props":1059,"children":1060},{},[1061],{"type":66,"value":1062},"or",{"type":66,"value":1064}," unset) counts against the\nscorecard regardless of pass. A test file that already failed on ",{"type":61,"tag":74,"props":1066,"children":1068},{"className":1067},[],[1069],{"type":66,"value":301},{"type":66,"value":1071},"\nis surfaced as ",{"type":61,"tag":74,"props":1073,"children":1075},{"className":1074},[],[1076],{"type":66,"value":1077},"pre_existing_unrelated",{"type":66,"value":1079}," and does not count — but is\nstill reported so the user can clean it up.",{"type":61,"tag":68,"props":1081,"children":1082},{},[1083,1085,1091,1093,1099],{"type":66,"value":1084},"Capture output to ",{"type":61,"tag":74,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":66,"value":1090},".mem0-integration\u002Ftest-stdout-flag-off.log",{"type":66,"value":1092}," and\n",{"type":61,"tag":74,"props":1094,"children":1096},{"className":1095},[],[1097],{"type":66,"value":1098},".mem0-integration\u002Ftest-stdout-flag-on.log",{"type":66,"value":1100},". Scorecard reports pass\u002Ffail\nper pass.",{"type":61,"tag":452,"props":1102,"children":1104},{"id":1103},"_5-smoke-test-real-api-call-shortest-round-trip",[1105],{"type":66,"value":1106},"5. Smoke test (real API call, shortest round-trip)",{"type":61,"tag":68,"props":1108,"children":1109},{},[1110,1112,1117,1119,1124,1126,1131],{"type":66,"value":1111},"Scripted end-to-end flow tailored to ",{"type":61,"tag":74,"props":1113,"children":1115},{"className":1114},[],[1116],{"type":66,"value":267},{"type":66,"value":1118},". The call shapes\nbelow are the minimal ones; if ",{"type":61,"tag":74,"props":1120,"children":1122},{"className":1121},[],[1123],{"type":66,"value":391},{"type":66,"value":1125}," names a delegated skill, use\n",{"type":61,"tag":726,"props":1127,"children":1128},{},[1129],{"type":66,"value":1130},"that skill's",{"type":66,"value":1132}," minimal example verbatim instead — it is the canonical\nshape for the detected stack.",{"type":61,"tag":68,"props":1134,"children":1135},{},[1136],{"type":61,"tag":242,"props":1137,"children":1138},{},[1139],{"type":66,"value":1140},"Platform (Python):",{"type":61,"tag":1142,"props":1143,"children":1147},"pre",{"className":1144,"code":1146,"language":66},[1145],"language-text","from mem0 import MemoryClient\nc = MemoryClient()                               # uses MEM0_API_KEY\nuid = f\"mem0-test-integration-{os.urandom(4).hex()}\"\nc.add([{\"role\": \"user\", \"content\": \"I prefer aisle seats\"}], user_id=uid)\nhits = c.search(\"seat preference\", user_id=uid)\nassert any(\"aisle\" in h.get(\"memory\", \"\") for h in hits), hits\nc.delete_all(user_id=uid)                        # clean up\n",[1148],{"type":61,"tag":74,"props":1149,"children":1151},{"__ignoreMap":1150},"",[1152],{"type":66,"value":1146},{"type":61,"tag":68,"props":1154,"children":1155},{},[1156,1161,1163,1169,1171,1177],{"type":61,"tag":242,"props":1157,"children":1158},{},[1159],{"type":66,"value":1160},"Platform (TS):",{"type":66,"value":1162}," same shape with ",{"type":61,"tag":74,"props":1164,"children":1166},{"className":1165},[],[1167],{"type":66,"value":1168},"MemoryClient",{"type":66,"value":1170}," from ",{"type":61,"tag":74,"props":1172,"children":1174},{"className":1173},[],[1175],{"type":66,"value":1176},"\"mem0ai\"",{"type":66,"value":490},{"type":61,"tag":68,"props":1179,"children":1180},{},[1181,1186,1188,1193,1194,1200,1202,1207,1209,1215],{"type":61,"tag":242,"props":1182,"children":1183},{},[1184],{"type":66,"value":1185},"OSS (Python \u002F TS):",{"type":66,"value":1187}," uses ",{"type":61,"tag":74,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":66,"value":860},{"type":66,"value":618},{"type":61,"tag":74,"props":1195,"children":1197},{"className":1196},[],[1198],{"type":66,"value":1199},"new Memory()",{"type":66,"value":1201}," with default config\n(OpenAI LLM via ",{"type":61,"tag":74,"props":1203,"children":1205},{"className":1204},[],[1206],{"type":66,"value":430},{"type":66,"value":1208},", local Qdrant). If the repo ships a\n",{"type":61,"tag":74,"props":1210,"children":1212},{"className":1211},[],[1213],{"type":66,"value":1214},"docker-compose.yml",{"type":66,"value":1216}," with a Qdrant service, the skill starts it first and\ntears it down after. If no backing store is reachable → fail with a\nclear message naming the fix.",{"type":61,"tag":68,"props":1218,"children":1219},{},[1220,1222,1227,1229,1235],{"type":66,"value":1221},"The smoke test always uses a ",{"type":61,"tag":242,"props":1223,"children":1224},{},[1225],{"type":66,"value":1226},"disposable random user_id",{"type":66,"value":1228}," prefixed with\n",{"type":61,"tag":74,"props":1230,"children":1232},{"className":1231},[],[1233],{"type":66,"value":1234},"mem0-test-integration-",{"type":66,"value":1236}," so a failed cleanup doesn't pollute the user's\nreal data. A background tidy step deletes any prefix-matching entries\nolder than 24 hours on the next run.",{"type":61,"tag":68,"props":1238,"children":1239},{},[1240,1241,1247],{"type":66,"value":1084},{"type":61,"tag":74,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":66,"value":1246},".mem0-integration\u002Fsmoke-stdout.log",{"type":66,"value":490},{"type":61,"tag":452,"props":1249,"children":1251},{"id":1250},"_6-e2e-integration-test-run-the-app-exercise-the-flow",[1252],{"type":66,"value":1253},"6. E2E integration test (run the app, exercise the flow)",{"type":61,"tag":68,"props":1255,"children":1256},{},[1257,1259],{"type":66,"value":1258},"Unit tests + smoke prove the SDK works in isolation. This step is the\nreal signal: ",{"type":61,"tag":242,"props":1260,"children":1261},{},[1262],{"type":66,"value":1263},"does memory actually appear in the app's user-visible\noutput when the integration runs end-to-end?",{"type":61,"tag":68,"props":1265,"children":1266},{},[1267,1269,1274,1276,1282,1284,1289,1291,1297,1299,1305],{"type":66,"value":1268},"Requires ",{"type":61,"tag":74,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":66,"value":391},{"type":66,"value":1275}," to contain an ",{"type":61,"tag":74,"props":1277,"children":1279},{"className":1278},[],[1280],{"type":66,"value":1281},"E2E recipe:",{"type":66,"value":1283}," section (authored by\n",{"type":61,"tag":74,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":66,"value":79},{"type":66,"value":1290}," step 5). If absent → status ",{"type":61,"tag":74,"props":1292,"children":1294},{"className":1293},[],[1295],{"type":66,"value":1296},"skipped",{"type":66,"value":1298}," (not ",{"type":61,"tag":74,"props":1300,"children":1302},{"className":1301},[],[1303],{"type":66,"value":1304},"fail",{"type":66,"value":1306},"),\nnote in scorecard that the repo has no runnable entry point.",{"type":61,"tag":68,"props":1308,"children":1309},{},[1310],{"type":66,"value":1311},"Recipe fields the skill reads:",{"type":61,"tag":103,"props":1313,"children":1314},{},[1315,1341,1384,1418,1429,1447,1458],{"type":61,"tag":107,"props":1316,"children":1317},{},[1318,1324,1326,1332,1334,1340],{"type":61,"tag":74,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":66,"value":1323},"start",{"type":66,"value":1325}," — shell command to launch the app using ",{"type":61,"tag":74,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":66,"value":1331},"$PORT",{"type":66,"value":1333}," for any network\nport. Run in background with stdout\u002Fstderr teed to\n",{"type":61,"tag":74,"props":1335,"children":1337},{"className":1336},[],[1338],{"type":66,"value":1339},".mem0-integration\u002Fe2e-app.log",{"type":66,"value":490},{"type":61,"tag":107,"props":1342,"children":1343},{},[1344,1350,1352,1358,1360,1366,1368,1374,1376,1382],{"type":61,"tag":74,"props":1345,"children":1347},{"className":1346},[],[1348],{"type":66,"value":1349},"ready_probe",{"type":66,"value":1351}," — how to detect readiness. ",{"type":61,"tag":74,"props":1353,"children":1355},{"className":1354},[],[1356],{"type":66,"value":1357},"url=... status=...",{"type":66,"value":1359}," polls an\nHTTP endpoint; ",{"type":61,"tag":74,"props":1361,"children":1363},{"className":1362},[],[1364],{"type":66,"value":1365},"log=\"...\"",{"type":66,"value":1367}," waits for a substring in ",{"type":61,"tag":74,"props":1369,"children":1371},{"className":1370},[],[1372],{"type":66,"value":1373},"e2e-app.log",{"type":66,"value":1375},";\n",{"type":61,"tag":74,"props":1377,"children":1379},{"className":1378},[],[1380],{"type":66,"value":1381},"sleep=N",{"type":66,"value":1383}," waits N seconds (last resort). 60-second hard timeout.",{"type":61,"tag":107,"props":1385,"children":1386},{},[1387,1393,1395,1401,1403,1408,1410,1416],{"type":61,"tag":74,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":66,"value":1392},"compose_services",{"type":66,"value":1394}," — optional. If set, bring them up via\n",{"type":61,"tag":74,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":66,"value":1400},"docker compose up -d \u003Cservices>",{"type":66,"value":1402}," before ",{"type":61,"tag":74,"props":1404,"children":1406},{"className":1405},[],[1407],{"type":66,"value":1323},{"type":66,"value":1409},", tear them down with\n",{"type":61,"tag":74,"props":1411,"children":1413},{"className":1412},[],[1414],{"type":66,"value":1415},"docker compose down",{"type":66,"value":1417}," at the end.",{"type":61,"tag":107,"props":1419,"children":1420},{},[1421,1427],{"type":61,"tag":74,"props":1422,"children":1424},{"className":1423},[],[1425],{"type":66,"value":1426},"write_call",{"type":66,"value":1428}," — triggers the Mem0 write path exactly once. Output is\ncaptured and surfaced on failure. 60-second hard timeout.",{"type":61,"tag":107,"props":1430,"children":1431},{},[1432,1438,1440,1445],{"type":61,"tag":74,"props":1433,"children":1435},{"className":1434},[],[1436],{"type":66,"value":1437},"write_async_wait_ms",{"type":66,"value":1439}," — pause after ",{"type":61,"tag":74,"props":1441,"children":1443},{"className":1442},[],[1444],{"type":66,"value":1426},{"type":66,"value":1446}," to let async memory\nflushes land. Default 0.",{"type":61,"tag":107,"props":1448,"children":1449},{},[1450,1456],{"type":61,"tag":74,"props":1451,"children":1453},{"className":1452},[],[1454],{"type":66,"value":1455},"read_call",{"type":66,"value":1457}," — triggers the Mem0 read path. Typically a fresh session\nor new request that should surface the stored memory.",{"type":61,"tag":107,"props":1459,"children":1460},{},[1461,1467,1469,1475,1477,1483,1485,1490],{"type":61,"tag":74,"props":1462,"children":1464},{"className":1463},[],[1465],{"type":66,"value":1466},"read_assert",{"type":66,"value":1468}," — substring, ",{"type":61,"tag":74,"props":1470,"children":1472},{"className":1471},[],[1473],{"type":66,"value":1474},"regex=...",{"type":66,"value":1476},", or ",{"type":61,"tag":74,"props":1478,"children":1480},{"className":1479},[],[1481],{"type":66,"value":1482},"jsonpath=\u003Cexpr>=\u003Cvalue>",{"type":66,"value":1484},"\nthat must appear in ",{"type":61,"tag":74,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":66,"value":1455},{"type":66,"value":1491},"'s stdout. This is the E2E pass gate.",{"type":61,"tag":68,"props":1493,"children":1494},{},[1495],{"type":66,"value":1496},"Execution order:",{"type":61,"tag":1498,"props":1499,"children":1500},"ol",{},[1501,1513,1534,1546,1558,1570,1581,1592,1602,1621],{"type":61,"tag":107,"props":1502,"children":1503},{},[1504,1506,1512],{"type":66,"value":1505},"Allocate an ephemeral TCP port; export as ",{"type":61,"tag":74,"props":1507,"children":1509},{"className":1508},[],[1510],{"type":66,"value":1511},"PORT",{"type":66,"value":490},{"type":61,"tag":107,"props":1514,"children":1515},{},[1516,1518,1524,1526,1532],{"type":66,"value":1517},"Set ",{"type":61,"tag":74,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":66,"value":1523},"MEM0_USER_ID",{"type":66,"value":1525}," to a disposable ",{"type":61,"tag":74,"props":1527,"children":1529},{"className":1528},[],[1530],{"type":66,"value":1531},"mem0-test-integration-\u003Crand>",{"type":66,"value":1533}," value\nand export it, so the app can use the same scoping the smoke test does\nif the recipe wants cleanup.",{"type":61,"tag":107,"props":1535,"children":1536},{},[1537,1539,1544],{"type":66,"value":1538},"Bring up ",{"type":61,"tag":74,"props":1540,"children":1542},{"className":1541},[],[1543],{"type":66,"value":1392},{"type":66,"value":1545}," if named.",{"type":61,"tag":107,"props":1547,"children":1548},{},[1549,1551,1556],{"type":66,"value":1550},"Run ",{"type":61,"tag":74,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":66,"value":1323},{"type":66,"value":1557}," in the background.",{"type":61,"tag":107,"props":1559,"children":1560},{},[1561,1563,1568],{"type":66,"value":1562},"Poll ",{"type":61,"tag":74,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":66,"value":1349},{"type":66,"value":1569}," until success or 60s timeout. Timeout → fail.",{"type":61,"tag":107,"props":1571,"children":1572},{},[1573,1574,1579],{"type":66,"value":1550},{"type":61,"tag":74,"props":1575,"children":1577},{"className":1576},[],[1578],{"type":66,"value":1426},{"type":66,"value":1580},". Non-zero exit → fail (but continue to cleanup).",{"type":61,"tag":107,"props":1582,"children":1583},{},[1584,1586,1591],{"type":66,"value":1585},"Sleep ",{"type":61,"tag":74,"props":1587,"children":1589},{"className":1588},[],[1590],{"type":66,"value":1437},{"type":66,"value":490},{"type":61,"tag":107,"props":1593,"children":1594},{},[1595,1596,1601],{"type":66,"value":1550},{"type":61,"tag":74,"props":1597,"children":1599},{"className":1598},[],[1600],{"type":66,"value":1455},{"type":66,"value":490},{"type":61,"tag":107,"props":1603,"children":1604},{},[1605,1607,1612,1614,1619],{"type":66,"value":1606},"Evaluate ",{"type":61,"tag":74,"props":1608,"children":1610},{"className":1609},[],[1611],{"type":66,"value":1466},{"type":66,"value":1613}," against ",{"type":61,"tag":74,"props":1615,"children":1617},{"className":1616},[],[1618],{"type":66,"value":1455},{"type":66,"value":1620},"'s stdout. Miss → fail.",{"type":61,"tag":107,"props":1622,"children":1623},{},[1624,1626,1631,1633,1639,1641,1647],{"type":66,"value":1625},"Cleanup (always, even on failure): SIGTERM the app, SIGKILL after\n5s, ",{"type":61,"tag":74,"props":1627,"children":1629},{"className":1628},[],[1630],{"type":66,"value":1415},{"type":66,"value":1632}," if services were started, ",{"type":61,"tag":74,"props":1634,"children":1636},{"className":1635},[],[1637],{"type":66,"value":1638},"delete_all",{"type":66,"value":1640},"\nmemories matching ",{"type":61,"tag":74,"props":1642,"children":1644},{"className":1643},[],[1645],{"type":66,"value":1646},"mem0-test-integration-*",{"type":66,"value":1648}," on Platform scenarios.",{"type":61,"tag":68,"props":1650,"children":1651},{},[1652],{"type":66,"value":1653},"On any failure, the scorecard includes:",{"type":61,"tag":103,"props":1655,"children":1656},{},[1657,1667,1679,1689],{"type":61,"tag":107,"props":1658,"children":1659},{},[1660,1662],{"type":66,"value":1661},"Last 40 lines of ",{"type":61,"tag":74,"props":1663,"children":1665},{"className":1664},[],[1666],{"type":66,"value":1373},{"type":61,"tag":107,"props":1668,"children":1669},{},[1670,1672,1677],{"type":66,"value":1671},"Full ",{"type":61,"tag":74,"props":1673,"children":1675},{"className":1674},[],[1676],{"type":66,"value":1426},{"type":66,"value":1678}," output",{"type":61,"tag":107,"props":1680,"children":1681},{},[1682,1683,1688],{"type":66,"value":1671},{"type":61,"tag":74,"props":1684,"children":1686},{"className":1685},[],[1687],{"type":66,"value":1455},{"type":66,"value":1678},{"type":61,"tag":107,"props":1690,"children":1691},{},[1692,1694],{"type":66,"value":1693},"The expected vs actual for ",{"type":61,"tag":74,"props":1695,"children":1697},{"className":1696},[],[1698],{"type":66,"value":1466},{"type":61,"tag":452,"props":1700,"children":1702},{"id":1701},"_7-scorecard",[1703],{"type":66,"value":1704},"7. Scorecard",{"type":61,"tag":68,"props":1706,"children":1707},{},[1708,1710,1716,1717,1723],{"type":66,"value":1709},"Write ",{"type":61,"tag":74,"props":1711,"children":1713},{"className":1712},[],[1714],{"type":66,"value":1715},".mem0-integration\u002Fscorecard.md",{"type":66,"value":809},{"type":61,"tag":74,"props":1718,"children":1720},{"className":1719},[],[1721],{"type":66,"value":1722},".mem0-integration\u002Fscorecard.json",{"type":66,"value":528},{"type":61,"tag":1142,"props":1725,"children":1728},{"className":1726,"code":1727,"language":66},[1145],"{\n  \"timestamp\": \"2026-04-20T14:03:11Z\",\n  \"branch\": \"mem0-integrate\u002Fremember-user-preferences\",\n  \"product\": \"platform\",\n  \"language\": \"python\",\n  \"mem0_version\": \"2.0.0\",\n  \"non_invasive\": true,\n  \"feature_flag\": \"MEM0_ENABLED\",\n  \"results\": {\n    \"install\":      {\"status\": \"pass\", \"duration_ms\": 12043},\n    \"static_checks\":{\"status\": \"pass\", \"duration_ms\": 812},\n    \"unit_tests_flag_off\": {\"status\": \"pass\", \"duration_ms\": 3920, \"count\": 47,\n                            \"reason\": \"all pre-existing tests green with flag unset\"},\n    \"unit_tests_flag_on\":  {\"status\": \"pass\", \"duration_ms\": 4321, \"count\": 49},\n    \"smoke_test\":   {\"status\": \"pass\", \"duration_ms\": 2890, \"memory_id\": \"mem_...\"},\n    \"e2e_test\":     {\"status\": \"pass\", \"duration_ms\": 14200,\n                     \"ready_probe_ms\": 3100, \"write_exit\": 0,\n                     \"read_assert_matched\": true}\n  },\n  \"friction\": {\n    \"dependency_install_retries\": 0,\n    \"pre_existing_test_failures\": 0,\n    \"warnings\": [\"mem0ai 2.0.0 pinned; consider 2.0.1 for fix X\"]\n  },\n  \"overall\": \"pass\"\n}\n",[1729],{"type":61,"tag":74,"props":1730,"children":1731},{"__ignoreMap":1150},[1732],{"type":66,"value":1727},{"type":61,"tag":68,"props":1734,"children":1735},{},[1736],{"type":66,"value":1737},"The markdown version is human-readable and includes:",{"type":61,"tag":103,"props":1739,"children":1740},{},[1741,1746,1751,1756,1761],{"type":61,"tag":107,"props":1742,"children":1743},{},[1744],{"type":66,"value":1745},"Goal doc + plan doc reprinted at top (so reviewers don't have to hunt).",{"type":61,"tag":107,"props":1747,"children":1748},{},[1749],{"type":66,"value":1750},"Each check with pass\u002Ffail + log excerpt.",{"type":61,"tag":107,"props":1752,"children":1753},{},[1754],{"type":66,"value":1755},"Friction summary.",{"type":61,"tag":107,"props":1757,"children":1758},{},[1759],{"type":66,"value":1760},"Verbatim warnings from mem0 SDK (if any — e.g., deprecated field usage).",{"type":61,"tag":107,"props":1762,"children":1763},{},[1764,1769],{"type":61,"tag":242,"props":1765,"children":1766},{},[1767],{"type":66,"value":1768},"Explicit \"NOT checked\" section",{"type":66,"value":1770}," listing what loose coupling misses:\n\"Whether the stored data is what the user wants stored. Whether search\nruns at the right moment. Whether user_id matches the actual session\nscope. Human review required.\"",{"type":61,"tag":452,"props":1772,"children":1774},{"id":1773},"_8-report-exit",[1775],{"type":66,"value":1776},"8. Report + exit",{"type":61,"tag":103,"props":1778,"children":1779},{},[1780,1785,1802],{"type":61,"tag":107,"props":1781,"children":1782},{},[1783],{"type":66,"value":1784},"Print the scorecard path + overall pass\u002Ffail to stdout.",{"type":61,"tag":107,"props":1786,"children":1787},{},[1788,1793,1795,1800],{"type":61,"tag":242,"props":1789,"children":1790},{},[1791],{"type":66,"value":1792},"Do not commit the scorecard files.",{"type":66,"value":1794}," They live in ",{"type":61,"tag":74,"props":1796,"children":1798},{"className":1797},[],[1799],{"type":66,"value":364},{"type":66,"value":1801},",\nwhich is gitignored. The user can inspect and optionally pin.",{"type":61,"tag":107,"props":1803,"children":1804},{},[1805],{"type":66,"value":1806},"On fail: print the first failing step's log tail (last 40 lines) and\nstop. Do not attempt to fix anything.",{"type":61,"tag":83,"props":1808,"children":1810},{"id":1809},"artifacts-all-under-mem0-integration",[1811,1813,1818],{"type":66,"value":1812},"Artifacts (all under ",{"type":61,"tag":74,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":66,"value":364},{"type":66,"value":1819},")",{"type":61,"tag":530,"props":1821,"children":1822},{},[1823,1844],{"type":61,"tag":534,"props":1824,"children":1825},{},[1826],{"type":61,"tag":538,"props":1827,"children":1828},{},[1829,1834,1839],{"type":61,"tag":542,"props":1830,"children":1831},{},[1832],{"type":66,"value":1833},"File",{"type":61,"tag":542,"props":1835,"children":1836},{},[1837],{"type":66,"value":1838},"Purpose",{"type":61,"tag":542,"props":1840,"children":1841},{},[1842],{"type":66,"value":1843},"Retention",{"type":61,"tag":553,"props":1845,"children":1846},{},[1847,1869,1890,1911,1932,1953,1973],{"type":61,"tag":538,"props":1848,"children":1849},{},[1850,1859,1864],{"type":61,"tag":560,"props":1851,"children":1852},{},[1853],{"type":61,"tag":74,"props":1854,"children":1856},{"className":1855},[],[1857],{"type":66,"value":1858},"scorecard.md",{"type":61,"tag":560,"props":1860,"children":1861},{},[1862],{"type":66,"value":1863},"Human-readable verdict.",{"type":61,"tag":560,"props":1865,"children":1866},{},[1867],{"type":66,"value":1868},"Overwritten per run.",{"type":61,"tag":538,"props":1870,"children":1871},{},[1872,1881,1886],{"type":61,"tag":560,"props":1873,"children":1874},{},[1875],{"type":61,"tag":74,"props":1876,"children":1878},{"className":1877},[],[1879],{"type":66,"value":1880},"scorecard.json",{"type":61,"tag":560,"props":1882,"children":1883},{},[1884],{"type":66,"value":1885},"Machine-readable verdict. Consumed by the CI scorecard workflow later.",{"type":61,"tag":560,"props":1887,"children":1888},{},[1889],{"type":66,"value":1868},{"type":61,"tag":538,"props":1891,"children":1892},{},[1893,1902,1907],{"type":61,"tag":560,"props":1894,"children":1895},{},[1896],{"type":61,"tag":74,"props":1897,"children":1899},{"className":1898},[],[1900],{"type":66,"value":1901},"test-stdout-flag-off.log",{"type":61,"tag":560,"props":1903,"children":1904},{},[1905],{"type":66,"value":1906},"Step 4 Pass A (pre-existing suite, flag unset).",{"type":61,"tag":560,"props":1908,"children":1909},{},[1910],{"type":66,"value":1868},{"type":61,"tag":538,"props":1912,"children":1913},{},[1914,1923,1928],{"type":61,"tag":560,"props":1915,"children":1916},{},[1917],{"type":61,"tag":74,"props":1918,"children":1920},{"className":1919},[],[1921],{"type":66,"value":1922},"test-stdout-flag-on.log",{"type":61,"tag":560,"props":1924,"children":1925},{},[1926],{"type":66,"value":1927},"Step 4 Pass B (full suite, flag set).",{"type":61,"tag":560,"props":1929,"children":1930},{},[1931],{"type":66,"value":1868},{"type":61,"tag":538,"props":1933,"children":1934},{},[1935,1944,1949],{"type":61,"tag":560,"props":1936,"children":1937},{},[1938],{"type":61,"tag":74,"props":1939,"children":1941},{"className":1940},[],[1942],{"type":66,"value":1943},"smoke-stdout.log",{"type":61,"tag":560,"props":1945,"children":1946},{},[1947],{"type":66,"value":1948},"Full output from step 5.",{"type":61,"tag":560,"props":1950,"children":1951},{},[1952],{"type":66,"value":1868},{"type":61,"tag":538,"props":1954,"children":1955},{},[1956,1964,1969],{"type":61,"tag":560,"props":1957,"children":1958},{},[1959],{"type":61,"tag":74,"props":1960,"children":1962},{"className":1961},[],[1963],{"type":66,"value":1373},{"type":61,"tag":560,"props":1965,"children":1966},{},[1967],{"type":66,"value":1968},"Background app stdout\u002Fstderr from step 6.",{"type":61,"tag":560,"props":1970,"children":1971},{},[1972],{"type":66,"value":1868},{"type":61,"tag":538,"props":1974,"children":1975},{},[1976,1985,1990],{"type":61,"tag":560,"props":1977,"children":1978},{},[1979],{"type":61,"tag":74,"props":1980,"children":1982},{"className":1981},[],[1983],{"type":66,"value":1984},"e2e-calls.log",{"type":61,"tag":560,"props":1986,"children":1987},{},[1988],{"type":66,"value":1989},"write_call + read_call invocations and outputs.",{"type":61,"tag":560,"props":1991,"children":1992},{},[1993],{"type":66,"value":1868},{"type":61,"tag":83,"props":1995,"children":1997},{"id":1996},"modes",[1998],{"type":66,"value":1999},"Modes",{"type":61,"tag":530,"props":2001,"children":2002},{},[2003,2024],{"type":61,"tag":534,"props":2004,"children":2005},{},[2006],{"type":61,"tag":538,"props":2007,"children":2008},{},[2009,2014,2019],{"type":61,"tag":542,"props":2010,"children":2011},{},[2012],{"type":66,"value":2013},"Mode",{"type":61,"tag":542,"props":2015,"children":2016},{},[2017],{"type":66,"value":2018},"Trigger",{"type":61,"tag":542,"props":2020,"children":2021},{},[2022],{"type":66,"value":2023},"Behavior",{"type":61,"tag":553,"props":2025,"children":2026},{},[2027,2053],{"type":61,"tag":538,"props":2028,"children":2029},{},[2030,2035,2048],{"type":61,"tag":560,"props":2031,"children":2032},{},[2033],{"type":66,"value":2034},"Interactive (default)",{"type":61,"tag":560,"props":2036,"children":2037},{},[2038,2040,2046],{"type":66,"value":2039},"TTY present, ",{"type":61,"tag":74,"props":2041,"children":2043},{"className":2042},[],[2044],{"type":66,"value":2045},"MEM0_TEST_CI",{"type":66,"value":2047}," unset",{"type":61,"tag":560,"props":2049,"children":2050},{},[2051],{"type":66,"value":2052},"Asks for missing keys, prints friendly summaries.",{"type":61,"tag":538,"props":2054,"children":2055},{},[2056,2061,2070],{"type":61,"tag":560,"props":2057,"children":2058},{},[2059],{"type":66,"value":2060},"CI",{"type":61,"tag":560,"props":2062,"children":2063},{},[2064],{"type":61,"tag":74,"props":2065,"children":2067},{"className":2066},[],[2068],{"type":66,"value":2069},"MEM0_TEST_CI=1",{"type":61,"tag":560,"props":2071,"children":2072},{},[2073],{"type":66,"value":2074},"Keys must be in env, no prompts, non-zero exit on any fail. JSON scorecard goes to stdout's tail for workflow parsing.",{"type":61,"tag":83,"props":2076,"children":2078},{"id":2077},"invocation",[2079],{"type":66,"value":2080},"Invocation",{"type":61,"tag":1142,"props":2082,"children":2085},{"className":2083,"code":2084,"language":66},[1145],"\u002Fmem0-test-integration                       # interactive, all steps\n\u002Fmem0-test-integration --ci                  # non-interactive\n\u002Fmem0-test-integration --skip-smoke          # no API calls, no E2E\n\u002Fmem0-test-integration --skip-e2e            # unit + smoke only (faster CI)\n\u002Fmem0-test-integration --only-smoke          # just smoke\n\u002Fmem0-test-integration --only-e2e            # just E2E (assumes deps installed)\n",[2086],{"type":61,"tag":74,"props":2087,"children":2088},{"__ignoreMap":1150},[2089],{"type":66,"value":2084},{"type":61,"tag":68,"props":2091,"children":2092},{},[2093,2095,2101,2103,2109,2111,2117],{"type":66,"value":2094},"Composition: ",{"type":61,"tag":74,"props":2096,"children":2098},{"className":2097},[],[2099],{"type":66,"value":2100},"--skip-*",{"type":66,"value":2102}," can stack (",{"type":61,"tag":74,"props":2104,"children":2106},{"className":2105},[],[2107],{"type":66,"value":2108},"--skip-smoke --skip-e2e",{"type":66,"value":2110}," = static +\nunit only, zero API cost). ",{"type":61,"tag":74,"props":2112,"children":2114},{"className":2113},[],[2115],{"type":66,"value":2116},"--only-*",{"type":66,"value":2118}," is mutually exclusive with all\nother flags.",{"type":61,"tag":83,"props":2120,"children":2122},{"id":2121},"exit-codes",[2123],{"type":66,"value":2124},"Exit codes",{"type":61,"tag":530,"props":2126,"children":2127},{},[2128,2144],{"type":61,"tag":534,"props":2129,"children":2130},{},[2131],{"type":61,"tag":538,"props":2132,"children":2133},{},[2134,2139],{"type":61,"tag":542,"props":2135,"children":2136},{},[2137],{"type":66,"value":2138},"Code",{"type":61,"tag":542,"props":2140,"children":2141},{},[2142],{"type":66,"value":2143},"Meaning",{"type":61,"tag":553,"props":2145,"children":2146},{},[2147,2160,2180,2193,2206,2219,2232,2245,2258],{"type":61,"tag":538,"props":2148,"children":2149},{},[2150,2155],{"type":61,"tag":560,"props":2151,"children":2152},{},[2153],{"type":66,"value":2154},"0",{"type":61,"tag":560,"props":2156,"children":2157},{},[2158],{"type":66,"value":2159},"All checks passed.",{"type":61,"tag":538,"props":2161,"children":2162},{},[2163,2168],{"type":61,"tag":560,"props":2164,"children":2165},{},[2166],{"type":66,"value":2167},"1",{"type":61,"tag":560,"props":2169,"children":2170},{},[2171,2173,2178],{"type":66,"value":2172},"Precondition failed (no ",{"type":61,"tag":74,"props":2174,"children":2176},{"className":2175},[],[2177],{"type":66,"value":364},{"type":66,"value":2179},", wrong branch, dirty tree).",{"type":61,"tag":538,"props":2181,"children":2182},{},[2183,2188],{"type":61,"tag":560,"props":2184,"children":2185},{},[2186],{"type":66,"value":2187},"2",{"type":61,"tag":560,"props":2189,"children":2190},{},[2191],{"type":66,"value":2192},"Missing env key (CI mode) or dependency install failure.",{"type":61,"tag":538,"props":2194,"children":2195},{},[2196,2201],{"type":61,"tag":560,"props":2197,"children":2198},{},[2199],{"type":66,"value":2200},"3",{"type":61,"tag":560,"props":2202,"children":2203},{},[2204],{"type":66,"value":2205},"Static sanity check failed (wrong import, type error).",{"type":61,"tag":538,"props":2207,"children":2208},{},[2209,2214],{"type":61,"tag":560,"props":2210,"children":2211},{},[2212],{"type":66,"value":2213},"4",{"type":61,"tag":560,"props":2215,"children":2216},{},[2217],{"type":66,"value":2218},"Unit tests failed (Pass B — integration itself broken).",{"type":61,"tag":538,"props":2220,"children":2221},{},[2222,2227],{"type":61,"tag":560,"props":2223,"children":2224},{},[2225],{"type":66,"value":2226},"5",{"type":61,"tag":560,"props":2228,"children":2229},{},[2230],{"type":66,"value":2231},"Smoke test failed.",{"type":61,"tag":538,"props":2233,"children":2234},{},[2235,2240],{"type":61,"tag":560,"props":2236,"children":2237},{},[2238],{"type":66,"value":2239},"6",{"type":61,"tag":560,"props":2241,"children":2242},{},[2243],{"type":66,"value":2244},"E2E test failed (ready_probe timeout, write\u002Fread call failed, or read_assert miss).",{"type":61,"tag":538,"props":2246,"children":2247},{},[2248,2253],{"type":61,"tag":560,"props":2249,"children":2250},{},[2251],{"type":66,"value":2252},"7",{"type":61,"tag":560,"props":2254,"children":2255},{},[2256],{"type":66,"value":2257},"Non-invasiveness violation: Pass A failed (pre-existing tests broke). Integrator's heal loop refuses to touch this.",{"type":61,"tag":538,"props":2259,"children":2260},{},[2261,2266],{"type":61,"tag":560,"props":2262,"children":2263},{},[2264],{"type":66,"value":2265},"8",{"type":61,"tag":560,"props":2267,"children":2268},{},[2269],{"type":66,"value":2270},"Internal error (skill bug — report it).",{"type":61,"tag":83,"props":2272,"children":2274},{"id":2273},"explicitly-out-of-scope",[2275],{"type":66,"value":2276},"Explicitly out of scope",{"type":61,"tag":103,"props":2278,"children":2279},{},[2280,2297,2307,2332,2357,2374],{"type":61,"tag":107,"props":2281,"children":2282},{},[2283,2288,2290,2295],{"type":61,"tag":242,"props":2284,"children":2285},{},[2286],{"type":66,"value":2287},"Modifying source files.",{"type":66,"value":2289}," The skill is read-only against the repo.\nIf verification exposes a bug, re-run ",{"type":61,"tag":74,"props":2291,"children":2293},{"className":2292},[],[2294],{"type":66,"value":79},{"type":66,"value":2296}," on the same\ngoal + plan; do not hand-patch.",{"type":61,"tag":107,"props":2298,"children":2299},{},[2300,2305],{"type":61,"tag":242,"props":2301,"children":2302},{},[2303],{"type":66,"value":2304},"Fixing broken tests.",{"type":66,"value":2306}," Failing unit tests are a signal that the\nintegration is wrong, not that the tests are wrong. The skill does\nnot \"try a different test.\"",{"type":61,"tag":107,"props":2308,"children":2309},{},[2310,2315,2317,2322,2324,2330],{"type":61,"tag":242,"props":2311,"children":2312},{},[2313],{"type":66,"value":2314},"Deep logical correctness.",{"type":66,"value":2316}," The E2E step proves \"something the user\nsaid earlier comes back later,\" which is a useful but shallow signal.\nIt does NOT prove the integration picks the ",{"type":61,"tag":726,"props":2318,"children":2319},{},[2320],{"type":66,"value":2321},"right",{"type":66,"value":2323}," facts to store,\nscopes ",{"type":61,"tag":74,"props":2325,"children":2327},{"className":2326},[],[2328],{"type":66,"value":2329},"user_id",{"type":66,"value":2331}," correctly across real users, or handles conflict\nresolution well. That's human review territory.",{"type":61,"tag":107,"props":2333,"children":2334},{},[2335,2340,2342,2347,2349,2355],{"type":61,"tag":242,"props":2336,"children":2337},{},[2338],{"type":66,"value":2339},"Self-healing.",{"type":66,"value":2341}," This skill never modifies source files. The paired\n",{"type":61,"tag":74,"props":2343,"children":2345},{"className":2344},[],[2346],{"type":66,"value":79},{"type":66,"value":2348}," skill in its default ",{"type":61,"tag":74,"props":2350,"children":2352},{"className":2351},[],[2353],{"type":66,"value":2354},"--heal",{"type":66,"value":2356}," mode consumes the\nscorecard produced here and drives its own remediation loop. Exit\ncode 7 (non-invasiveness violation) is the explicit signal the heal\nloop must stop and surface to the user.",{"type":61,"tag":107,"props":2358,"children":2359},{},[2360,2365,2367,2372],{"type":61,"tag":242,"props":2361,"children":2362},{},[2363],{"type":66,"value":2364},"Cross-branch comparisons.",{"type":66,"value":2366}," No ",{"type":61,"tag":74,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":66,"value":301},{"type":66,"value":2373}," baseline diffing. The\nscorecard reflects this branch only.",{"type":61,"tag":107,"props":2375,"children":2376},{},[2377,2382],{"type":61,"tag":242,"props":2378,"children":2379},{},[2380],{"type":66,"value":2381},"Running against production data.",{"type":66,"value":2383}," Every smoke test uses a disposable\nrandom user_id and cleans up after. Never touches any other user's data.",{"items":2385,"total":2527},[2386,2398,2410,2424,2438,2452,2464,2473,2484,2498,2510,2520],{"slug":2387,"name":2387,"fn":2388,"description":2389,"org":2390,"tags":2391,"stars":26,"repoUrl":27,"updatedAt":2397},"context-loader","load project context from Mem0","Searches and injects relevant memories into context before starting work on a task. Use when beginning a new task, switching context, or when project history, past decisions, or coding conventions need to be loaded.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2392,2393,2396],{"name":21,"slug":22,"type":16},{"name":2394,"slug":2395,"type":16},"Context","context",{"name":18,"slug":19,"type":16},"2026-07-13T06:13:15.682218",{"slug":2399,"name":2399,"fn":2400,"description":2401,"org":2402,"tags":2403,"stars":26,"repoUrl":27,"updatedAt":2409},"dream","consolidate and prune stored memories","Consolidates stored memories by merging duplicates, resolving contradictions, and pruning stale entries. Use when memory count is high, search results feel noisy or repetitive, or periodic cleanup is needed to maintain memory quality.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2404,2405,2408],{"name":21,"slug":22,"type":16},{"name":2406,"slug":2407,"type":16},"Data Cleaning","data-cleaning",{"name":18,"slug":19,"type":16},"2026-07-13T06:12:54.000421",{"slug":2411,"name":2411,"fn":2412,"description":2413,"org":2414,"tags":2415,"stars":26,"repoUrl":27,"updatedAt":2423},"export","export project memories to Markdown files","Exports all project memories to a portable Markdown file for backup or migration. Use when backing up memories, migrating to another project, sharing memory state with teammates, or archiving before cleanup.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2416,2419,2420],{"name":2417,"slug":2418,"type":16},"Backup","backup",{"name":18,"slug":19,"type":16},{"name":2421,"slug":2422,"type":16},"Migration","migration","2026-07-13T06:13:05.091831",{"slug":2425,"name":2425,"fn":2426,"description":2427,"org":2428,"tags":2429,"stars":26,"repoUrl":27,"updatedAt":2437},"forget","delete outdated or incorrect memories","Deletes memories by search query or memory ID with confirmation before removal. Use when removing outdated decisions, incorrect memories, sensitive data, or cleaning up after experiments. Also handles undo of recent additions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2430,2433,2434],{"name":2431,"slug":2432,"type":16},"Maintenance","maintenance",{"name":18,"slug":19,"type":16},{"name":2435,"slug":2436,"type":16},"Privacy","privacy","2026-07-13T06:13:00.862899",{"slug":2439,"name":2439,"fn":2440,"description":2441,"org":2442,"tags":2443,"stars":26,"repoUrl":27,"updatedAt":2451},"health","diagnose Mem0 connectivity and health","Diagnoses mem0 connectivity, API key validity, and memory read\u002Fwrite functionality. Use when memory operations fail, searches return empty, add_memory errors occur, MCP connection drops, or to verify the plugin is working correctly.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2444,2447,2448],{"name":2445,"slug":2446,"type":16},"Debugging","debugging",{"name":18,"slug":19,"type":16},{"name":2449,"slug":2450,"type":16},"Monitoring","monitoring","2026-07-13T06:13:06.569475",{"slug":2453,"name":2453,"fn":2454,"description":2455,"org":2456,"tags":2457,"stars":26,"repoUrl":27,"updatedAt":2463},"import","import project memories from Markdown files","Imports memories from an exported Markdown file or MEMORY.md into the current project. Use when migrating from another project, restoring from backup, importing Claude Code native MEMORY.md content, or setting up a new project with existing knowledge.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2458,2461,2462],{"name":2459,"slug":2460,"type":16},"Markdown","markdown",{"name":18,"slug":19,"type":16},{"name":2421,"slug":2422,"type":16},"2026-07-13T06:12:59.389494",{"slug":2465,"name":2465,"fn":2466,"description":2467,"org":2468,"tags":2469,"stars":26,"repoUrl":27,"updatedAt":2472},"list-projects","list projects with stored memories","Lists all projects with stored memories for the current user, showing memory counts and last activity dates. Use when checking which projects have memories, comparing memory distribution across repos, or finding a specific project scope.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2470,2471],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},"2026-07-13T06:13:27.80043",{"slug":8,"name":8,"fn":2474,"description":2475,"org":2476,"tags":2477,"stars":26,"repoUrl":27,"updatedAt":2483},"add persistent memory to AI applications","Mem0 Platform SDK for adding persistent memory to AI applications. TRIGGER when: user mentions \"mem0\", \"MemoryClient\", \"memory layer\", \"remember user preferences\", \"persistent context\", \"personalization\", or needs to add long-term memory to chatbots, agents, or AI apps. Covers Python SDK (mem0ai), TypeScript SDK (mem0ai), and framework integrations (LangChain, CrewAI, OpenAI Agents SDK, Pipecat, LlamaIndex, AutoGen, LangGraph). Also covers the open-source self-hosted Memory class. This is the DEFAULT mem0 skill for ambiguous queries. DO NOT TRIGGER when: user asks about CLI commands, terminal usage, or shell scripts (use mem0-cli), or Vercel AI SDK \u002F @mem0\u002Fvercel-ai-provider \u002F createMem0 (use mem0-vercel-ai-sdk).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2478,2479,2482],{"name":21,"slug":22,"type":16},{"name":2480,"slug":2481,"type":16},"AI Infrastructure","ai-infrastructure",{"name":18,"slug":19,"type":16},"2026-07-13T06:12:42.552904",{"slug":2485,"name":2485,"fn":2486,"description":2487,"org":2488,"tags":2489,"stars":26,"repoUrl":27,"updatedAt":2497},"mem0-cli","manage Mem0 memory via command line","Mem0 CLI -- the command-line interface for mem0 memory operations. TRIGGER when: user mentions \"mem0 cli\", \"mem0 command line\", \"@mem0\u002Fcli\", \"mem0-cli\", \"pip install mem0-cli\", \"npm install -g @mem0\u002Fcli\", or is running mem0 commands in a terminal\u002Fshell (mem0 add, mem0 search, mem0 list, mem0 get, mem0 init, mem0 config, mem0 import). Also triggers when query includes CLI flags like --user-id, --output, --json, --agent, or describes bash\u002Fzsh\u002Fterminal\u002Fshell usage. DO NOT TRIGGER when: user asks about programmatic SDK integration in Python\u002FTS code (use mem0 skill), or Vercel AI SDK provider (use mem0-vercel-ai-sdk skill).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2490,2493,2496],{"name":2491,"slug":2492,"type":16},"Automation","automation",{"name":2494,"slug":2495,"type":16},"CLI","cli",{"name":18,"slug":19,"type":16},"2026-07-13T06:12:48.46494",{"slug":2499,"name":2499,"fn":2500,"description":2501,"org":2502,"tags":2503,"stars":26,"repoUrl":27,"updatedAt":2509},"mem0-integrate","integrate Mem0 into repositories","Integrate Mem0 into an existing repository using a goal-driven, TDD pipeline. Detects the repo's language automatically and asks the user to pick between Mem0 Platform (managed) and Mem0 Open Source (self-hosted). Writes failing tests before any implementation. Produces a local feature branch plus `.mem0-integration\u002F` artifacts consumed by the paired verification skill. TRIGGER when: user says \"integrate mem0\", \"add mem0 to this repo\", \"wire mem0 into \u003Crepo>\", or asks how to add memory to an existing project. DO NOT TRIGGER when: the user wants general SDK usage (use skill:mem0), CLI usage (use skill:mem0-cli), or Vercel AI SDK (use skill:mem0-vercel-ai-sdk). After success, invoke skill:mem0-test-integration to verify in the same workspace (loose coupling).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2504,2505,2508],{"name":21,"slug":22,"type":16},{"name":2506,"slug":2507,"type":16},"API Development","api-development",{"name":18,"slug":19,"type":16},"2026-07-13T06:12:46.60755",{"slug":2511,"name":2511,"fn":2512,"description":2513,"org":2514,"tags":2515,"stars":26,"repoUrl":27,"updatedAt":2519},"mem0-oss-to-platform","migrate Mem0 projects to platform","Plan and then execute a migration of a project from the mem0 open-source \u002F self-hosted SDK (the local `Memory` class) to the mem0 Platform \u002F hosted \u002F managed SDK (the `MemoryClient` class). Use this whenever a developer wants to move, switch, or migrate their mem0 usage off OSS\u002Fself-hosted to the hosted API — e.g. \"migrate my mem0 setup to the platform\", \"switch from self-hosted mem0 to MemoryClient\", \"use my mem0 API key instead of a local Qdrant\", \"move mem0 to the cloud\u002Fhosted\u002Fmanaged service\", or \"replace my local mem0 vector store + embedder config with the platform\". Applies to Python (`from mem0 import Memory` → `from mem0 import MemoryClient`) and TypeScript\u002FJavaScript (`import { Memory } from \"mem0ai\u002Foss\"` → `import MemoryClient from \"mem0ai\"`). Trigger even when the user doesn't say the word \"migrate\" but clearly wants their existing mem0 integration to run against the hosted platform. It first produces a reviewable migration plan, then executes it after the developer approves. Strictly scoped to the mem0 integration — it does not refactor, restructure, or \"improve\" any unrelated code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2516,2517,2518],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":2421,"slug":2422,"type":16},"2026-07-13T06:12:43.848266",{"slug":4,"name":4,"fn":5,"description":6,"org":2521,"tags":2522,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2523,2524,2525,2526],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},23,{"items":2529,"total":2527},[2530,2536,2542,2548,2554,2560,2566],{"slug":2387,"name":2387,"fn":2388,"description":2389,"org":2531,"tags":2532,"stars":26,"repoUrl":27,"updatedAt":2397},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2533,2534,2535],{"name":21,"slug":22,"type":16},{"name":2394,"slug":2395,"type":16},{"name":18,"slug":19,"type":16},{"slug":2399,"name":2399,"fn":2400,"description":2401,"org":2537,"tags":2538,"stars":26,"repoUrl":27,"updatedAt":2409},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2539,2540,2541],{"name":21,"slug":22,"type":16},{"name":2406,"slug":2407,"type":16},{"name":18,"slug":19,"type":16},{"slug":2411,"name":2411,"fn":2412,"description":2413,"org":2543,"tags":2544,"stars":26,"repoUrl":27,"updatedAt":2423},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2545,2546,2547],{"name":2417,"slug":2418,"type":16},{"name":18,"slug":19,"type":16},{"name":2421,"slug":2422,"type":16},{"slug":2425,"name":2425,"fn":2426,"description":2427,"org":2549,"tags":2550,"stars":26,"repoUrl":27,"updatedAt":2437},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2551,2552,2553],{"name":2431,"slug":2432,"type":16},{"name":18,"slug":19,"type":16},{"name":2435,"slug":2436,"type":16},{"slug":2439,"name":2439,"fn":2440,"description":2441,"org":2555,"tags":2556,"stars":26,"repoUrl":27,"updatedAt":2451},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2557,2558,2559],{"name":2445,"slug":2446,"type":16},{"name":18,"slug":19,"type":16},{"name":2449,"slug":2450,"type":16},{"slug":2453,"name":2453,"fn":2454,"description":2455,"org":2561,"tags":2562,"stars":26,"repoUrl":27,"updatedAt":2463},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2563,2564,2565],{"name":2459,"slug":2460,"type":16},{"name":18,"slug":19,"type":16},{"name":2421,"slug":2422,"type":16},{"slug":2465,"name":2465,"fn":2466,"description":2467,"org":2567,"tags":2568,"stars":26,"repoUrl":27,"updatedAt":2472},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2569,2570],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16}]