[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-6172fdd8-f2dd-4a64-bdb3-ca12fc585e32":3,"$ffDyxooDvF10oDmyqmAt9gKMI-PTotR91kujxYYWNKIY":42},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":33},"6172fdd8-f2dd-4a64-bdb3-ca12fc585e32","data-structure-protocol","为代理提供代码库的持久结构化记忆——导航依赖关系、跟踪公共API，并理解连接存在的原因，无需重新阅读整个仓库。","cat_coding_backend","mod_coding","sickn33,coding","---\nname: data-structure-protocol\ndescription: \"Give agents persistent structural memory of a codebase — navigate dependencies, track public APIs, and understand why connections exist without re-reading the whole repo.\"\nrisk: safe\nsource: \"https:\u002F\u002Fgithub.com\u002Fk-kolomeitsev\u002Fdata-structure-protocol\"\ndate_added: \"2026-02-27\"\n---\n\n# Data Structure Protocol (DSP)\n\nLLM coding agents lose context between tasks. On large codebases they spend most of their tokens on \"orientation\" — figuring out where things live, what depends on what, and what is safe to change. DSP solves this by externalizing the project's structural map into a persistent, queryable graph stored in a `.dsp\u002F` directory next to the code.\n\nDSP is NOT documentation for humans and NOT an AST dump. It captures three things: **meaning** (why an entity exists), **boundaries** (what it imports and exposes), and **reasons** (why each connection exists). This is enough for an agent to navigate, refactor, and generate code without loading the entire source tree into the context window.\n\n## When to Use\nUse this skill when:\n- The project has a `.dsp\u002F` directory (DSP is already set up)\n- The user asks to set up DSP, bootstrap, or map a project's structure\n- Creating, modifying, or deleting code files in a DSP-tracked project (to keep the graph updated)\n- Navigating project structure, understanding dependencies, or finding specific modules\n- The user mentions DSP, dsp-cli, `.dsp`, or structure mapping\n- Performing impact analysis before a refactor or dependency replacement\n\n## Core Concepts\n\n### Code = graph\n\nDSP models the codebase as a directed graph. Nodes are **entities**, edges are **imports** and **shared\u002Fexports**.\n\nTwo entity kinds exist:\n- **Object**: any \"thing\" that isn't a function (module\u002Ffile\u002Fclass\u002Fconfig\u002Fresource\u002Fexternal dependency)\n- **Function**: an exported function\u002Fmethod\u002Fhandler\u002Fpipeline\n\n### Identity by UID, not by file path\n\nEvery entity gets a stable UID: `obj-\u003C8hex>` for objects, `func-\u003C8hex>` for functions. File paths are attributes that can change; UIDs survive renames, moves, and reformatting.\n\nFor entities inside a file, the UID is anchored with a comment marker in source code:\n\n```js\n\u002F\u002F @dsp func-7f3a9c12\nexport function calculateTotal(items) { ... }\n```\n\n```python\n# @dsp obj-e5f6g7h8\nclass UserService:\n```\n\n### Every connection has a \"why\"\n\nWhen an import is recorded, DSP stores a short reason explaining *why* that dependency exists. This lives in the `exports\u002F` reverse index of the imported entity. A dependency graph without reasons tells you *what imports what*; reasons tell you **what is safe to change and who will break**.\n\n### Storage format\n\nEach entity gets a small directory under `.dsp\u002F`:\n\n```\n.dsp\u002F\n├── TOC                        # ordered list of all entity UIDs from root\n├── obj-a1b2c3d4\u002F\n│   ├── description            # source path, kind, purpose (1-3 sentences)\n│   ├── imports                # UIDs this entity depends on (one per line)\n│   ├── shared                 # UIDs of public API \u002F exported entities\n│   └── exports\u002F               # reverse index: who imports this and why\n│       ├── \u003Cimporter_uid>     # file content = \"why\" text\n│       └── \u003Cshared_uid>\u002F\n│           ├── description    # what is exported\n│           └── \u003Cimporter_uid> # why this specific export is imported\n└── func-7f3a9c12\u002F\n    ├── description\n    ├── imports\n    └── exports\u002F\n```\n\nEverything is plain text. Diffable. Reviewable. No database needed.\n\n### Full import coverage\n\nEvery file or artifact that is imported anywhere must be represented in `.dsp` as an Object — code, images, styles, configs, JSON, wasm, everything. External dependencies (npm packages, stdlib, etc.) are recorded as `kind: external` but their internals are never analyzed.\n\n## How It Works\n\n### Initial Setup\n\nThe skill relies on a standalone Python CLI script `dsp-cli.py`. If it is missing from the project, download it:\n\n```bash\ncurl -O https:\u002F\u002Fraw.githubusercontent.com\u002Fk-kolomeitsev\u002Fdata-structure-protocol\u002Fmain\u002Fskills\u002Fdata-structure-protocol\u002Fscripts\u002Fdsp-cli.py\n```\n\nRequires **Python 3.10+**. All commands use `python dsp-cli.py --root \u003Cproject-root> \u003Ccommand>`.\n\n### Bootstrap (initial mapping)\n\nIf `.dsp\u002F` is empty, traverse the project from root entrypoint(s) via DFS on imports:\n\n1. Identify root entrypoints (`package.json` main, framework entry, `main.py`, etc.)\n2. Document the root file: `create-object`, `create-function` for each export, `create-shared`, `add-import` for all dependencies\n3. Take the first non-external import, document it fully, descend into its imports\n4. Backtrack when no unvisited local imports remain; continue until all reachable files are documented\n5. External dependencies: `create-object --kind external`, add to TOC, but never descend into `node_modules`\u002F`site-packages`\u002Fetc.\n\n### Workflow Rules\n\n- **Before changing code**: Find affected entities via `search`, `find-by-source`, or `read-toc`. Read their `description` and `imports` to understand context.\n- **When creating a file\u002Fmodule**: Call `create-object`. For each exported function — `create-function` (with `--owner`). Register exports via `create-shared`.\n- **When adding an import**: Call `add-import` with a brief `why`. For external deps — first `create-object --kind external` if the entity doesn't exist.\n- **When removing import\u002Fexport\u002Ffile**: Call `remove-import`, `remove-shared`, `remove-entity`. Cascade cleanup is automatic.\n- **When renaming\u002Fmoving a file**: Call `move-entity`. UID does not change.\n- **Don't touch DSP** if only internal implementation changed without affecting purpose or dependencies.\n\n### Key Commands\n\n| Category | Commands |\n|----------|----------|\n| **Create** | `init`, `create-object`, `create-function`, `create-shared`, `add-import` |\n| **Update** | `update-description`, `update-import-why`, `move-entity` |\n| **Delete** | `remove-import`, `remove-shared`, `remove-entity` |\n| **Navigate** | `get-entity`, `get-children --depth N`, `get-parents --depth N`, `get-path`, `get-recipients`, `read-toc` |\n| **Search** | `search \u003Cquery>`, `find-by-source \u003Cpath>` |\n| **Diagnostics** | `detect-cycles`, `get-orphans`, `get-stats` |\n\n### When to Update DSP\n\n| Code Change | DSP Action |\n|---|---|\n| New file\u002Fmodule | `create-object` + `create-function` + `create-shared` + `add-import` |\n| New import added | `add-import` (+ `create-object --kind external` if new dep) |\n| Import removed | `remove-import` |\n| Export added | `create-shared` (+ `create-function` if new) |\n| Export removed | `remove-shared` |\n| File renamed\u002Fmoved | `move-entity` |\n| File deleted | `remove-entity` |\n| Purpose changed | `update-description` |\n| Internal-only change | **No DSP update needed** |\n\n## Examples\n\n### Example 1: Setting up DSP and documenting a module\n\n```bash\npython dsp-cli.py --root . init\n\npython dsp-cli.py --root . create-object \"src\u002Fapp.ts\" \"Main application entrypoint\"\n# Output: obj-a1b2c3d4\n\npython dsp-cli.py --root . create-function \"src\u002Fapp.ts#start\" \"Starts the HTTP server\" --owner obj-a1b2c3d4\n# Output: func-7f3a9c12\n\npython dsp-cli.py --root . create-shared obj-a1b2c3d4 func-7f3a9c12\n\npython dsp-cli.py --root . add-import obj-a1b2c3d4 obj-deadbeef \"HTTP routing\"\n```\n\n### Example 2: Navigating the graph before making changes\n\n```bash\npython dsp-cli.py --root . search \"authentication\"\npython dsp-cli.py --root . get-entity obj-a1b2c3d4\npython dsp-cli.py --root . get-children obj-a1b2c3d4 --depth 2\npython dsp-cli.py --root . get-recipients obj-a1b2c3d4\npython dsp-cli.py --root . get-path obj-a1b2c3d4 func-7f3a9c12\n```\n\n### Example 3: Impact analysis before replacing a library\n\n```bash\npython dsp-cli.py --root . find-by-source \"lodash\"\n# Output: obj-11223344\n\npython dsp-cli.py --root . get-recipients obj-11223344\n# Shows every module that imports lodash and WHY — lets you systematically replace it\n```\n\n## Best Practices\n\n- ✅ **Do:** Update DSP immediately when creating new files, adding imports, or changing public APIs\n- ✅ **Do:** Always add a meaningful `why` reason when recording an import — this is where most of DSP's value lives\n- ✅ **Do:** Use `kind: external` for third-party libraries without analyzing their internals\n- ✅ **Do:** Keep descriptions minimal (1-3 sentences about purpose, not implementation)\n- ✅ **Do:** Treat `.dsp\u002F` diffs like code diffs — review them, keep them accurate\n- ❌ **Don't:** Touch `.dsp\u002F` for internal-only changes that don't affect purpose or dependencies\n- ❌ **Don't:** Change an entity's UID on rename\u002Fmove (use `move-entity` instead)\n- ❌ **Don't:** Create UIDs for every local variable or helper — only file-level Objects and public\u002Fshared entities\n\n## Integration\n\nThis skill connects naturally to:\n- **context-compression** — DSP reduces the need for compression by providing targeted retrieval instead of loading everything\n- **context-optimization** — DSP is a structural optimization: agents pull minimal \"context bundles\" instead of raw source\n- **architecture** — DSP captures architectural boundaries (imports\u002Fexports) that feed system design decisions\n\n## References\n\n- **Full architecture specification**: [ARCHITECTURE.md](https:\u002F\u002Fgithub.com\u002Fk-kolomeitsev\u002Fdata-structure-protocol\u002Fblob\u002Fmain\u002FARCHITECTURE.md)\n- **CLI source + reference docs**: [skills\u002Fdata-structure-protocol](https:\u002F\u002Fgithub.com\u002Fk-kolomeitsev\u002Fdata-structure-protocol\u002Ftree\u002Fmain\u002Fskills\u002Fdata-structure-protocol)\n- **Introduction article**: [article.md](https:\u002F\u002Fgithub.com\u002Fk-kolomeitsev\u002Fdata-structure-protocol\u002Fblob\u002Fmain\u002Farticle.md)\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.\n","","imported","https:\u002F\u002Fgithub.com\u002Fsickn33\u002Fantigravity-awesome-skills","user_system_seed","SkillOPIC",true,241,619,"2026-05-16 13:14:06",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"编程开发","coding","mdi-code-braces","代码生成、调试、审查，提升开发效率",2,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":25,"skillCount":32,"createdAt":26},"后端开发","backend","mdi-server","API、数据库、服务端架构",296,[34],{"id":35,"skillId":4,"version":36,"fileName":37,"fileSize":38,"filePath":39,"fileHash":40,"manifest":41,"createdAt":19},"05e97751-0537-4998-b1e9-f05a9cc29575","1.0.0","data-structure-protocol.zip",4085,"uploads\u002Fskills\u002F6172fdd8-f2dd-4a64-bdb3-ca12fc585e32\u002Fdata-structure-protocol.zip","ae06ecfafc857d0d13514cae79c3144c4b8d4c6a53484d139a802f4005a8f8a7","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":9968}]",{"code":43,"message":44,"data":45},200,"success",{"items":46,"stats":47,"page":50},[],{"averageRating":48,"totalRatings":48,"ratingCounts":49},0,[48,48,48,48,48],{"limit":51,"offset":48,"hasMore":52,"nextOffset":51,"ratedOnly":16},15,false]