Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosGoogle Cloud Tech: Gemini is coming to your city(24.09.2026 um 15:00 Uhr)
AI & KI NachrichtenGoogle’s latest moonshot to put machine learning in space(24.09.2026 um 15:12 Uhr)
Windows Tipps & SecurityPoll: What's your favorite Surface of 2026?(24.09.2026 um 14:58 Uhr)
Sichere ProgrammierungStreaming Materialized Views for Live Read Models (2026)(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA Day Is Not 86400 Seconds: The DST Bug in Your Date Math(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungSetting up Traefik: reverse proxy with automatic HTTPS(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA 200 OK response does not prove a secret leak(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungHow hot do you like it?(24.09.2026 um 15:05 Uhr)
YouTube Security VideosGoogle Cloud Tech: Gemini is coming to your city(24.09.2026 um 15:00 Uhr)
AI & KI NachrichtenGoogle’s latest moonshot to put machine learning in space(24.09.2026 um 15:12 Uhr)
Windows Tipps & SecurityPoll: What's your favorite Surface of 2026?(24.09.2026 um 14:58 Uhr)
Sichere ProgrammierungStreaming Materialized Views for Live Read Models (2026)(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA Day Is Not 86400 Seconds: The DST Bug in Your Date Math(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungSetting up Traefik: reverse proxy with automatic HTTPS(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungA 200 OK response does not prove a secret leak(24.09.2026 um 15:02 Uhr)
Sichere ProgrammierungHow hot do you like it?(24.09.2026 um 15:05 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Turn any git repo into llm readable format

Recently I came across a repo that allows you to talk to any github repo, its called Talk to Github. After looking at their codebase, I found an interesting repo that makes this site possible, and that is git ingest. In this post I will be…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Recently I came across a repo that allows you to talk to any github repo, its called Talk to Github. After looking at their codebase, I found an interesting repo that makes this site possible, and that is git ingest. In this post I will be going into details on how this repo works and how I made a JS implementation with image/pdf processing.



This repo turns any publicly available github repo and turns it into llm friendly format. Here is an example of turn gitingest repo into llm friendly format:



example llm format



First, it clones it repo into a temporary directory, then by traversing through every folder and files, it will convert the file name and file content into llm readable format. It also filters out unnecessary folders and files like .git folder an package-lock.json. One downside is that it also filters documents like images and pdfs. The program also allows you to ingest the codebase at any commit, it will first clone the repo and checkout the commit before converting them into llm format.



Like any typical js dev, I decided to write my own implementation in js and add image/pdf processing with gemini and the latest mistral-ocr model.



Heres what I need to do:




  • Clone the input repo

  • checkout to the commit/branch if given

  • loop through every files, filters out the ignored patterns and process them

  • converts them into llm readable format like gitingest

  • deletes the cloned repo in disk






1. Clone the repo && 2. checkout commit/branch



Since this requires shell command, I decided to use bun for the entire project. Bun has a bun in shell command $ which is super convenient to run shell command and get its output (output is not used in this case). My approach is to clone the repo into a random generated folder name under a tmp folder.



This is how I clone the git repo, I decided to make it to accept any git provider as it shouldnt add much complexity




import { $ } from 'bun'
import { nanoid } from 'nanoid'

const commit = '' // ur commit id (if given)
const branch = '' // ur branch name (if given)

const id = nanoid()
const dir = `tmp/${id}`
const cloneArgs = []
if (!commit) {
cloneArgs.push('--depth=1') // save disk space
}
if (branch && !['main', 'master'].includes(branch)) {
cloneArgs.push('--branch', branch)
}
await $`git clone ${repo} ${cloneArgs.join(' ')} tmp/${id}`

if (commit) {
await $`cd ${dir} && git checkout ${commit}`
}









3. loop through every files, filters out the ignored patterns and process them



The original implementation in gitingest repo using node system, and uses a recursive method to process the node (folder/file) and its children (if folder). When the node is a folder, it will call the process with each of its children as the argument, and when the node is a file, it will return its name and content. Things changed a bit when the file is an image or pdf, we have to use gemini to describe the image and mistral-ocr to accurately process the pdf. Here is the js implementation of it:



ignore-patterns.ts




import ignore = require('ignore')

// from gitingest (removed images (images are readable now) and some dotfiles (more context on the project))
export const patterns = [
// Python
'*.pyc',
'*.pyo',
'*.pyd',
'__pycache__',
'.pytest_cache',
'.coverage',
'.tox',
'.nox',
'.mypy_cache',
'.ruff_cache',
'.hypothesis',
'poetry.lock',
'Pipfile.lock',
// JavaScript/FileSystemNode
'node_modules',
'bower_components',
'package-lock.json',
'yarn.lock',
'.npm',
'.yarn',
'.pnpm-store',
'bun.lock',
'bun.lockb',
// Java
'*.class',
'*.jar',
'*.war',
'*.ear',
'*.nar',
'.gradle/',
'build/',
'.settings/',
'.classpath',
'gradle-app.setting',
'*.gradle',
// IDEs and editors / Java
'.project',
// C/C++
'*.o',
'*.obj',
'*.dll',
'*.dylib',
'*.exe',
'*.lib',
'*.out',
'*.a',
'*.pdb',
// Swift/Xcode
'.build/',
'*.xcodeproj/',
'*.xcworkspace/',
'*.pbxuser',
'*.mode1v3',
'*.mode2v3',
'*.perspectivev3',
'*.xcuserstate',
'xcuserdata/',
'.swiftpm/',
// Ruby
'*.gem',
'.bundle/',
'vendor/bundle',
'Gemfile.lock',
'.ruby-version',
'.ruby-gemset',
'.rvmrc',
// Rust
'Cargo.lock',
'**/*.rs.bk',
// Java / Rust
'target/',
// Go
'pkg/',
// .NET/C//
'obj/',
'*.suo',
'*.user',
'*.userosscache',
'*.sln.docstates',
'packages/',
'*.nupkg',
// Go / .NET / C//
'bin/',
// Version control
'.git',
'.svn',
'.hg',
// Virtual environments
'venv',
'.venv',
'env',
'virtualenv',
// Temporary and cache files
'*.log',
'*.bak',
'*.swp',
'*.tmp',
'*.temp',
'.cache',
'.sass-cache',
'.eslintcache',
'.DS_Store',
'Thumbs.db',
'desktop.ini',
// Build directories and artifacts
'build',
'dist',
'target',
'out',
'*.egg-info',
'*.egg',
'*.whl',
'*.so',
// Documentation
'site-packages',
'.docusaurus',
'.next',
'.nuxt',
// Other common patterns
// Minified files
'*.min.js',
'*.min.css',
// Source maps
'*.map',
// Terraform
'.terraform',
'*.tfstate*',
// Dependencies in various languages
'vendor/',
]

const ig = ignore().add(patterns)

export const isIgnored = (file: string) => {
return ig.ignores(file)
}









import { createGoogleGenerativeAI } from '@ai-sdk/google'
import { Mistral } from '@mistralai/mistralai'
import { OCRResponse } from '@mistralai/mistralai/models/components'
import { generateText } from 'ai'
import * as path from 'path'
import { isIgnored } from './ignore-patterns'

const google = Bun.env.GEMINI_API_KEY
? createGoogleGenerativeAI({
apiKey: Bun.env.GEMINI_API_KEY,
})
: null

const mistral = Bun.env.MISTRAL_API_KEY
? new Mistral({
apiKey: Bun.env.MISTRAL_API_KEY,
})
: null

async function getAllFilesStats(rootPath: string, dirPath: string) {
const files = await fs.readdir(dirPath)
const arrayOfFiles: {
path: string
type: string
content: string
pdfParsed?: OCRResponse
imageDescription?: string
}[] = []

for (const file of files) {
const filePath = path.join(dirPath, file)
const bunFile = Bun.file(filePath)
const fileStat = await bunFile.stat()

if (isIgnored(path.relative(rootPath, filePath))) {
continue
}

if (fileStat.isDirectory()) {
arrayOfFiles.push(
...(await getAllFilesStats(rootPath, filePath)),
)
} else {
if (bunFile.type.startsWith('application/pdf') && mistral) {
const base64 = (await bunFile.bytes()).toBase64()

arrayOfFiles.push({
path: path.relative(rootPath, filePath),
type: bunFile.type,
content: await bunFile.text(),
pdfParsed: await mistral.ocr.process({
model: 'mistral-ocr-latest',
document: {
type: 'document_url',
documentUrl: 'data:application/pdf;base64,' + base64,
},
includeImageBase64: true,
}),
})
} else if (bunFile.type.startsWith('image/') && google) {
const arrayBuffer = await bunFile.arrayBuffer()
const { text } = await generateText({
model: google('gemini-2.0-flash'),
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: `
Description this image as detailed as possible
Dont make any unneccessary comments like "Here's a detailed description of the image"
The description is most likely going to be used to improve other llm's understanding of the image, so give as much details as possible
Only generate the description of the image, no chatting
`
,
},
{ type: 'image', image: arrayBuffer },
],
},
],
})

arrayOfFiles.push({
path: path.relative(rootPath, filePath),
type: bunFile.type,
content: await bunFile.text(),
imageDescription: text,
})
} else {
arrayOfFiles.push({
path: path.relative(rootPath, filePath),
type: bunFile.type,
content: await bunFile.text(),
})
}
}
}

return arrayOfFiles
}









4. converts them into llm readable format like gitingest



Since our data structure contains image description and parsed pdf information, we have to take that into account when convert each file information into llm format




import { OCRResponse } from '@mistralai/mistralai/models/components'

const formatFiles = (
files: {
path: string
type: string
content: string
pdfParsed?: OCRResponse
imageDescription?: string
}[],
) => {
const text = files
.map((file) => {
let output = '='.repeat(48)
output += '\n'
output += 'FILE: ' + file.path.split('/').pop()
output += '\n'
output += '='.repeat(48)
output += '\n'
output +=
file.type.split(';')[0] === 'application/pdf'
? JSON.stringify(file.pdfParsed)
: file.type.split(';')[0].startsWith('image/')
? file.imageDescription
: file.content
return output
})
.join('\n\n')
return text
}









5. deletes the cloned repo in disk






import * as fs from 'node:fs/promises'

await fs.rm(dir, { recursive: true, force: true })






There are some improves that can be made to this, the obvious one is to also process the generated pdf data from mistral. We can also improves the performance by storing the result into a db and returns it to the user on repeated requests. I have the db implementation already in the github repo below.



JS Implementation: github



You can also directly deploy it on railway: on click deploy



Thank you for reading, checkout my github profile https://github.com/TZGyn for my other open source projects. I love writing my own implementation of other projects to improve my knowledge and skill.

CTI Threat Relationship Graph3 Knoten / 2 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
SOC Incident Playbook: Remote Code Execution (RCE) Defense
title: Detect Exploitation - Turn any git repo into llm readable format
id: 13b54cf6-5690-4107-855b-62fd85429fe6
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-24
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-24"
        description = "YARA Signature for "
    strings:
        $str = "Turn any git repo into llm rea" ascii wide
    condition:
        any of them
}
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Turn any git repo into llm readable form.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Turn any git repo into llm readable format

Thematisch verwandte Begriffe: Turn, repo, into, readable · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-97152 | Nanomsg versions 0.5-beta through 1.x before 1.2.3 has a remotely exploi…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick