{"id":28265983,"url":"https://github.com/yoavst/graffiti","last_synced_at":"2025-06-15T07:30:57.225Z","repository":{"id":82627945,"uuid":"502321594","full_name":"yoavst/Graffiti","owner":"yoavst","description":"Create customized callgraph directly from your favorite IDE","archived":false,"fork":false,"pushed_at":"2025-03-18T18:33:14.000Z","size":8962,"stargazers_count":62,"open_issues_count":1,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-20T13:15:14.806Z","etag":null,"topics":["callgraph","jadx-gui","jeb","jeb-decompiler","jeb-python-scripts","mermaid","vscode-extension"],"latest_commit_sha":null,"homepage":"https://graffiti.quest/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yoavst.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-11T10:50:40.000Z","updated_at":"2025-05-19T17:25:47.000Z","dependencies_parsed_at":"2023-12-22T12:16:11.628Z","dependency_job_id":"5a7be577-8df3-4902-8d9a-cc0f40a2e30a","html_url":"https://github.com/yoavst/Graffiti","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/yoavst/Graffiti","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavst%2FGraffiti","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavst%2FGraffiti/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavst%2FGraffiti/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavst%2FGraffiti/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yoavst","download_url":"https://codeload.github.com/yoavst/Graffiti/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavst%2FGraffiti/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259940469,"owners_count":22935283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["callgraph","jadx-gui","jeb","jeb-decompiler","jeb-python-scripts","mermaid","vscode-extension"],"created_at":"2025-05-20T13:14:13.922Z","updated_at":"2025-06-15T07:30:57.212Z","avatar_url":"https://github.com/yoavst.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Graffiti\n\nCreate customized callgraph directly from your favorite editor.\n\n![Preview](docs/images/screenshots/screenshot.png)\n\n## Features\n\n- Add a node to the callgraph directly from your editor.\n- You choose what to add and where.\n- Open the selected node in the editor using right click.\n- Add text nodes, and comments\n- Export the graph to mermaid, svg or png\n- The graph support scrolling and zooming\n- Auto save to localstorage, can export to file.\n- Multiple tabs\n- Rename in the editor? the change will propagate to the graph.\n\n## Setup\n\nThe setup consits of three components: server, website, IDE Connect. See [Architecture section](#architecture) for more info.\n\n1. **Server** - Download and run `server.pyz` using python3: `python3 server.pyz` .\n2. **Website** - Open [graffiti.quest](https://graffiti.quest) in your browser.\n   - You can also serve the files from `graffiti_frontend_web_with_deps.zip` with your favorite http server.\n3. **IDE Connect** -\n   - press `?` on the website to open the help screen.\n   - Download the artifact for your chosen IDE.\n   - Click the `Docs` button for your chosen IDE to see specific installation details.\n\nNow you need the configure the website and the IDE plugin to connect through the server.\n\n1. **Website** - Click the connect button on the top right of the screen. The background will change to green on successful attempt.  \n   ![Click the connect button](docs/images/screenshots/website_how_to_connect.png)\n2. **IDE** - Follow the explanation in the usage section of the `?` docs.  \n   ![Connect from IDE](docs/images/screenshots/ide_how_to_connect.png)\n\n## Usage\n\nGraffiti represents a graph of entries from the code. The rule of thumb is:\n\n\u003e A new node will be added as a child of the currently selected node in the website\n\nYou can select a node in the graph by clicking on it. Pressing escape will unselect the node.\n\n### Adding a new node\n\nTo add a node, go to your chosen IDE and position your cursor inside a function (or field in supported platforms).\nNow, use the following shortcuts to add the current function to the graph\n\n- Ctrl+Shift+A - Add a new node to the graph.\n- Ctrl+Shift+X - Add a new node to the graph with a custom text on the edge.\n\nIn some of the IDEs we also support adding a line node - a node representing specific line in the source file/binary.  \nSome IDEs also support adding all the xrefs of a symbol.\n\n![Adding node to graph](docs/images/screenshots/add_to_graph.png)\n\n### Jumping to the source\n\nIf you right click on a node, it will open the symbol in your connected IDE.\n\n![Jumping to source](docs/images/screenshots/jump_to_source.png)\n\n### And much more\n\nTo learn about advance features of graffiti, use the `?` screen to read the docs of the Web UI. You can also you the command palette at `ctrl+shift+p` to explore all the available commands.\n\n## Backends\n\n| Editor      | Languages                               | add to graph | open in editor | Rename support | Field support | Add line to graph | Add xrefs | Socket type |\n| ----------- | --------------------------------------- | ------------ | -------------- | -------------- | ------------- | ----------------- | --------- | ----------- |\n| JEB         | Java                                    | ✅           | ✅             | ✅             | ✅            | ✅                | ✅        | TCP         |\n| Intellij    | Java, Kotlin, Go, C, C++, PHP, Python   | ✅           | ✅             | ❌             | ✅            | ✅                | ✅        | TCP         |\n| CLion       | C, C++                                  | ✅           | ✅             | ❌             | ✅            | ✅                | ✅        | TCP         |\n| PHPStorm    | PHP                                     | ✅           | ✅             | ❌             | ✅            | ✅                | ✅        | TCP         |\n| PyCharm     | Python                                  | ✅           | ✅             | ❌             | ✅            | ✅                | ✅        | TCP         |\n| GoLand      | Go                                      | ✅           | ✅             | ❌             | ✅            | ✅                | ✅        | TCP         |\n| Rubymine    | Ruby                                    | ✅           | ✅             | ❌             | ❌            | ✅                | ✅        | TCP         |\n| VSCode      | Depends on available language server    | ✅           | ✅             | ❌             | ❌            | ✅                | ❌        | TCP         |\n| IDA         | \\*                                      | ✅           | ✅             | ✅             | -             | ✅                | ✅        | TCP         |\n| Ghidra      | \\*                                      | ✅           | ✅             | ✅             | -             | ✅                | ❌        | TCP         |\n| Jadx        | Java                                    | ✅           | ✅             | ✅             | ✅            | ❌                | ✅        | TCP         |\n| OpenGrok    | Java, C, C++, Go, Kotlin unless indexed | ✅           | ✅             | -              | ❌            | ✅                | ❌        | Websocket   |\n| Sourcegraph | Java, C, C++, Go, Kotlin                | ✅           | ✅             | -              | ❌            | ✅                | ❌        | Websocket   |\n| Github      | Java, C, C++, Go, Kotlin                | ✅           | ✅             | -              | ❌            | ✅                | ❌        | Websocket   |\n| Gitlab      | Java, C, C++, Go, Kotlin                | ✅           | ✅             | -              | ❌            | ✅                | ❌        | Websocket   |\n\nYou can build all the backends using `make`, or build specific backend by running its own task.\n\nCheck [here](docs/platforms) for instructions for using graffiti on each supported platform\n\n## Architecture\n\n![Architecture](docs/images/architecture.svg)\nGraffiti was built with the following assumptions:\n\n- You might use more than a single editor for a project.\n- You might want to run everything locally.\n- It should be easy to use.\n\nGraffiti consists of 3 separate components\n\n- **Backend** - the editor used to browse code. The editor might be native, therefore supporting TCP sockets. However, some editors are inside a browser (for example: OpenGrok). Chrome doesn't support TCP Sockets, so Backend should be able to communicate with WebSocket as well. Backend should implement the following functionality:\n  - Add to graph - Send the current focused symbol.\n  - Pull - Get a symbol's address from the socket and open it in the editor\n  - (Optional) Rename - detect rename in the editor and notify the socket.\n- **Frontend** - Shows the call graph and allow you to interact with it. Should support:\n  - Layout the nodes\n  - Navigating the graph\n  - Import and export graph\n  - Undo, Redo\n  - etc...\n- **Server** - A middleware between the backend and the frontend. Support multiple of them in the same time, by multiplexing all the requests.\n  Need to support: - TCP editor connection - WebSocket editor connection - Websocket frontend connection\n\n### Multi user support\n\nMulti user support works by requiring each connected frontend/backend to supply a token.\nA token represent the namespace of a single user. Messages from the same user will only be delievered to its components.\n\nOn the first time you try to connect to a multi-user server with any backend, it will ask you for the token to use. You can retreive it from the web frontend,\nby clicking the key button on the top right of the screen. The frontend token is saved to localstorage so you can count it to remain the same.\n\nTo make it more user friendly, the backends cache the token under `~/.graffiti/token` on MacOS/Linux, `%USERPROFILE%/.graffiti/token` on Windows.\n\n## Patches\n\n### Mermaid\n\nThe project apply the following patch to support comments on the web frontend:\n\n```diff\ndiff --git a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js\nindex 5ed06723..dc0fde0e 100644\n--- a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js\n+++ b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js\n@@ -902,6 +902,7 @@ export const draw = async function (text, id, _version, diagObj) {\n   });\n\n   insertChildren(graph.children, parentLookupDb);\n+  if (window.elk_beforeCallback) window.elk_beforeCallback(id, graph)\n   log.info('after layout', JSON.stringify(graph, null, 2));\n   const g = await elk.layout(graph);\n   drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);\n```\n\n### NinjaKeys\n\nThe projects patches out the hotkey registeration of ninja keys, since it has a bug:\n\n```diff\ndiff a/ninja-keys/src/ninja-keys.ts b/ninja-keys/src/ninja-keys.ts\n--- a/ninja-keys/src/ninja-keys.ts\n+++ b/ninja-keys/src/ninja-keys.ts\n@@ -223,10 +223,0 @@ override update(changedProperties: PropertyValues\u003cthis\u003e) {\n-      this._flatData\n-        .filter((action) =\u003e !!action.hotkey)\n-        .forEach((action) =\u003e {\n-          hotkeys(action.hotkey!, (event) =\u003e {\n-            event.preventDefault();\n-            if (action.handler) {\n-              action.handler(action);\n-            }\n-          });\n-        });\n```\n\n# Credits\n\nThe logo icons created by Freepik - Flaticon.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoavst%2Fgraffiti","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoavst%2Fgraffiti","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoavst%2Fgraffiti/lists"}