Skip to main content

devkg-sparql

Query the Dev Knowledge Graph via SPARQL instead of grepping raw session files. Use this when asked about technologies, relationships between tools, session history, where a topic was discussed, or cross-platform knowledge. Prefer provenance-first SPARQL (message + session) over label-only CONTAINS or grep.

소스 정보

저장소
robertoshimizu/session-graph
최근 소스 활동
2026년 7월 29일 20:45
감지된 SKILL.md 언어
영어
스타
112
포크
18

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
devkg-sparql
description
Query the Dev Knowledge Graph via SPARQL instead of grepping raw session files. Use this when asked about technologies, relationships between tools, session history, where a topic was discussed, or cross-platform knowledge. Prefer provenance-first SPARQL (message + session) over label-only CONTAINS or grep.
user-invocable
true
allowed-tools
["Bash(curl:*)","Bash(jq:*)"]
# DevKG SPARQL Query Skill ## CRITICAL CONTEXT-SAFETY RULE **NEVER READ LARGE SPARQL RESULTS, SESSION FILES, JSONL, LOGS, OR GENERATED ARTIFACTS ALL AT ONCE.** Always add `LIMIT`, select only needed variables, inspect counts first, and summarize. Never dump huge result sets, ID lists, raw JSON, or transcript content into chat. Query the developer knowledge graph at `http://localhost:3030/devkg/sparql` via SPARQL. This graph contains extracted knowledge triples, entities, Wikidata links, and session metadata from **Claude Code, pi, Codex, Cursor, ChatGPT, DeepSeek, Grok, and Warp** sessions. **Content limit:** `sioc:content` on messages is capped at ~2000 characters at ingest. SPARQL is enough to **locate sessions and reason lightly** from triples + snippets. For full quotes or deep thread reconstruction, normalize `hasSourceFile` and read the JSONL only when needed. ## Retrieval Strategy (read this first) | User intent | Do this first | Do NOT start with | |-------------|---------------|-------------------| | "Where / which sessions discussed X?" | **Template 5** (topic + intent + provenance) | Label-only Template 6, or grep | | "What do we know about technology X?" | Template 1 (entity + provenance) | Grep | | "How does X relate to Y?" | Template 2 | Grep | | "Find the exact message wording" | Template 5 or 9 → then JSONL only if snippet truncated | Grepping all projects | **Default for session-discovery questions:** multi-signal filter (topic **and** intent terms) on **both** triple labels and `sioc:content`, always joining `extractedFrom` / `extractedInSession`, ordered by `DESC(?created)`, with `LIMIT`. When Fuseki returns provenance hits, **do not** fall back to grep. Grep only if Fuseki is down or returns 0 rows after a provenance query. ## Execution Pattern Always use this pattern (POST, URL-encoded query, JSON output). Include Fuseki auth when required: ```bash curl -s -X POST 'http://localhost:3030/devkg/sparql' \ -u admin:admin \ -H 'Accept: application/sparql-results+json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode "query=YOUR_SPARQL_HERE" \ | jq -r '.results.bindings[] | [.var1.value, .var2.value] | @tsv' ``` Adjust the `jq` expression to match your SELECT variables. Use `@tsv` for compact tabular output. Always `LIMIT` results. For multi-line queries, use double quotes around the `--data-urlencode` value and escape inner quotes: ```bash curl -s -X POST 'http://localhost:3030/devkg/sparql' \ -u admin:admin \ -H 'Accept: application/sparql-results+json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode "query=PREFIX devkg: <http://devkg.local/ontology#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT DISTINCT ?label WHERE { ?e a devkg:Entity ; rdfs:label ?label . FILTER(LANG(?label) = \"\") } LIMIT 10" \ | jq -r '.results.bindings[] | .label.value' ``` ## Fallback Rule If Fuseki is unreachable (curl fails or times out) **or** a provenance query (Template 5/8) returns 0 results, then fall back to grep-based session search: ```bash grep -rli "keyword" ~/.claude/projects ~/.pi/agent/sessions ~/.cursor/projects 2>/dev/null | head -20 ``` Then read matching JSONL files with bounded Python extraction. Only use this as a last resort. ## Resolving `hasSourceFile` to Disk (and Pruned Sources) `hasSourceFile` is NOT always a real absolute path. Normalize before any `Read`: | `hasSourceFile` prefix | Real on-disk location | |---|---| | `/Users/...` | absolute path — use as-is | | `/claude-sessions/<munged>/<file>` | `~/.claude/projects/<munged>/<file>` | | `/pi-sessions/<munged>/<file>` | `~/.pi/agent/sessions/<munged>/<file>` | | `/codex-sessions/<path>` | `~/.codex/sessions/<path>` | | `/cursor-sessions/projects/<slug>/...` | `~/.cursor/projects/<slug>/...` | ```bash resolve_session_path() { local sf="$1" p="" case "$sf" in /Users/*) p="$sf" ;; /claude-sessions/*) p="$HOME/.claude/projects/${sf#/claude-sessions/}" ;; /pi-sessions/*) p="$HOME/.pi/agent/sessions/${sf#/pi-sessions/}" ;; /codex-sessions/*) p="$HOME/.codex/sessions/${sf#/codex-sessions/}" ;; /cursor-sessions/projects/*) p="$HOME/.cursor/projects/${sf#/cursor-sessions/projects/}" ;; *) p="$sf" ;; esac local stem="${p%.jsonl}" if [ -f "$p" ]; then echo "FILE:$p"; return; fi if [ -f "$stem" ]; then echo "FILE:$stem"; return; fi if [ -d "$stem/subagents" ]; then echo "SUBAGENTS:$stem/subagents"; return; fi if [ -d "$p/subagents" ]; then echo "SUBAGENTS:$p/subagents"; return; fi echo "PRUNED:$p" } ``` **If the path is `PRUNED`**, do NOT grep the filesystem. Re-query KnowledgeTriples for that session via `extractedInSession` and reconstruct from labels + any remaining `sioc:content`. ## Result Formatting Present SPARQL results as markdown tables. Never dump raw JSON to the user. ## Prefixes (copy into every query) ```sparql PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX prov: <http://www.w3.org/ns/prov#> PREFIX sioc: <http://rdfs.org/sioc/ns#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX devkg: <http://devkg.local/ontology#> PREFIX data: <http://devkg.local/data/> PREFIX wd: <http://www.wikidata.org/entity/> ``` ## Ontology Cheat Sheet ### Classes | Class | Parent | Description | |-------|--------|-------------| | `devkg:Session` | `prov:Activity`, `sioc:Forum` | A working session (conversation) | | `devkg:Message` | `sioc:Post`, `prov:Entity` | A message in a session | | `devkg:UserMessage` | `devkg:Message` | Human message | | `devkg:AssistantMessage` | `devkg:Message` | AI message | | `devkg:ToolCall` | `prov:Activity` | Legacy tool invocation nodes (may be absent in new ingests — do not rely on them) | | `devkg:ToolResult` | `prov:Entity` | Legacy tool output (may be absent in new ingests) | | `devkg:CodeArtifact` | `prov:Entity`, `schema:SoftwareSourceCode` | Code file/snippet | | `devkg:Entity` | `prov:Entity` | Extracted technical concept | | `devkg:KnowledgeTriple` | — | Reified triple (subject→predicate→object) with provenance | | `devkg:Project` | `prov:Entity` | A development project | | `devkg:Developer` | `prov:Agent` | Human developer | | `devkg:AIModel` | `prov:Agent` | AI model (Claude, GPT, etc.) | | `devkg:Topic` | `skos:Concept` | Knowledge topic | ### Structural Predicates (Session/Message graph) | Predicate | Domain → Range | Notes | |-----------|---------------|-------| | `devkg:usedInSession` | Message/ToolCall → Session | Links content to its session | | `devkg:hasParentMessage` | Message → Message | Thread structure | | `devkg:mentionsTopic` | Message → Topic | Topic tagging | | `devkg:invokedTool` | AssistantMessage → ToolCall | Tool usage | | `devkg:hasToolResult` | ToolCall → ToolResult | Tool output | | `devkg:producedArtifact` | Activity → CodeArtifact | Code generation | | `devkg:belongsToProject` | Session → Project | Project membership | | `devkg:extractedFrom` | KnowledgeTriple → Message | Triple provenance | | `devkg:extractedInSession` | KnowledgeTriple → Session | Triple provenance | | `devkg:tripleSubject` | KnowledgeTriple → Entity | Reified subject | | `devkg:tripleObject` | KnowledgeTriple → Entity | Reified object | | `devkg:triplePredicateLabel` | KnowledgeTriple → xsd:string | Predicate name | ### Key Datatype Properties | Property | On | Value | |----------|----|-------| | `sioc:content` | Message | Message text (truncated ~2000 chars at ingest) | | `rdfs:label` | Entity/Session/Project | Display name | | `dcterms:created` | Session/Message | ISO datetime | | `devkg:hasSourcePlatform` | Session | `claude-code`, `pi-coding-agent`, `codex`, `cursor`, `chatgpt`, `deepseek`, `grok`, `warp` | | `devkg:hasSourceFile` | Session | Logical path to raw source — normalize before `Read` (see "Resolving `hasSourceFile` to Disk") | | `devkg:hasToolName` | ToolCall | Legacy — prefer KnowledgeTriples + message content for discovery | | `devkg:hasWorkingDirectory` | Session | Project directory path | | `owl:sameAs` | Entity | Wikidata URI (e.g., `wd:Q28865`) | ### Knowledge Predicates (24 total) These connect `devkg:Entity` to `devkg:Entity` via direct edges AND are stored as `devkg:triplePredicateLabel` strings on reified `devkg:KnowledgeTriple` nodes: `uses`, `dependsOn`, `enables`, `isPartOf`, `hasPart`, `implements`, `extends`, `alternativeTo`, `solves`, `produces`, `configures`, `composesWith`, `provides`, `requires`, `isTypeOf`, `builtWith`, `deployedOn`, `storesIn`, `queriedWith`, `integratesWith`, `broader`, `narrower`, `relatedTo`, `servesAs` ## Query Templates ### 1. Entity Lookup — "What do we know about X?" Returns all relationships (outbound + inbound) for an entity, with source file and content snippet for provenance. Use `CONTAINS` for fuzzy matching. ```sparql SELECT DISTINCT ?direction ?predicate ?otherLabel ?sourceFile ?platform (SUBSTR(?content, 1, 150) AS ?snippet) WHERE { { ?triple a devkg:KnowledgeTriple ; devkg:tripleSubject ?s ; devkg:triplePredicateLabel ?predicate ; devkg:tripleObject ?o ; devkg:extractedFrom ?msg ; devkg:extractedInSession ?session . ?s rdfs:label ?sLabel . ?o rdfs:label ?otherLabel . FILTER(CONTAINS(LCASE(STR(?sLabel)), "ENTITY_LOWER")) BIND("outbound" AS ?direction) } UNION { ?triple a devkg:KnowledgeTriple ; devkg:tripleSubject ?o ; devkg:triplePredicateLabel ?predicate ; devkg:tripleObject ?obj ; devkg:extractedFrom ?msg ; devkg:extractedInSession ?session . ?obj rdfs:label ?oLabel . ?o rdfs:label ?otherLabel . FILTER(CONTAINS(LCASE(STR(?oLabel)), "ENTITY_LOWER")) BIND("inbound" AS ?direction) } OPTIONAL { ?session devkg:hasSourceFile ?sourceFile } OPTIONAL { ?session devkg:hasSourcePlatform ?platform } OPTIONAL { ?msg sioc:content ?content } } ORDER BY ?direction ?predicate ``` Replace `ENTITY_LOWER` with the lowercase entity name (e.g., `neo4j`, `opentelemetry`). The `sourceFile` column is a logical path to the original JSONL/JSON file — normalize it with `resolve_session_path` (see "Resolving `hasSourceFile` to Disk") before `Read`; if it resolves to `PRUNED`, reconstruct from the triples instead. ### 2. Entity-to-Entity — "How does X relate to Y?" ```sparql SELECT DISTINCT ?predicate ?sourceSnippet WHERE { ?triple a devkg:KnowledgeTriple ; devkg:tripleSubject ?s ; devkg:triplePredicateLabel ?predicate ; devkg:tripleObject ?o ; devkg:extractedFrom ?msg . ?s rdfs:label ?sLabel . ?o rdfs:label ?oLabel . OPTIONAL { ?msg sioc:content ?c . BIND(SUBSTR(?c, 1, 150) AS ?sourceSnippet) } FILTER( CONTAINS(LCASE(STR(?sLabel)), "ENTITY_X") && CONTAINS(LCASE(STR(?oLabel)), "ENTITY_Y") ) } ``` ### 3. Predicate Search — "What uses/enables/solves X?" ```sparql SELECT DISTINCT ?subjectLabel ?objectLabel WHERE { ?triple a devkg:KnowledgeTriple ; devkg:tripleSubject ?s ; devkg:triplePredicateLabel "PREDICATE" ;
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기