MCPcopy Create free account
hub / github.com/Noumena-Network/code / readLocalTeamMemory

Function readLocalTeamMemory

src/services/teamMemorySync/index.ts:565–671  ·  view source on GitHub ↗

* Read all team memory files from the local directory into a flat key-value map. * Keys are relative paths from the team memory directory. * Empty files are included (content will be empty string). * * PSR M22174: Each file is scanned for credentials before inclusion * using patterns from gitle

(maxEntries: number | null)

Source from the content-addressed store, hash-verified

563 * warn the user.
564 */
565async function readLocalTeamMemory(maxEntries: number | null): Promise<{
566 entries: Record<string, string>
567 skippedSecrets: SkippedSecretFile[]
568}> {
569 const teamDir = getTeamMemPath()
570 const entries: Record<string, string> = {}
571 const skippedSecrets: SkippedSecretFile[] = []
572
573 async function walkDir(dir: string): Promise<void> {
574 try {
575 const dirEntries = await readdir(dir, { withFileTypes: true })
576 await Promise.all(
577 dirEntries.map(async entry => {
578 const fullPath = join(dir, entry.name)
579 if (entry.isDirectory()) {
580 await walkDir(fullPath)
581 } else if (entry.isFile()) {
582 try {
583 const stats = await stat(fullPath)
584 if (stats.size > MAX_FILE_SIZE_BYTES) {
585 logForDebugging(
586 `team-memory-sync: skipping oversized file ${entry.name} (${stats.size} > ${MAX_FILE_SIZE_BYTES} bytes)`,
587 { level: 'info' },
588 )
589 return
590 }
591 const content = await readFile(fullPath, 'utf8')
592 const relPath = relative(teamDir, fullPath).replaceAll('\\', '/')
593
594 // PSR M22174: scan for secrets BEFORE adding to the upload
595 // payload. If a secret is detected, skip this file entirely
596 // so it never leaves the machine.
597 const secretMatches = scanForSecrets(content)
598 if (secretMatches.length > 0) {
599 // Report only the first match per file — one secret is
600 // enough to skip the file and we don't want to log more
601 // than necessary about credential locations.
602 const firstMatch = secretMatches[0]!
603 skippedSecrets.push({
604 path: relPath,
605 ruleId: firstMatch.ruleId,
606 label: firstMatch.label,
607 })
608 logForDebugging(
609 `team-memory-sync: skipping "${relPath}" — detected ${firstMatch.label}`,
610 { level: 'warn' },
611 )
612 return
613 }
614
615 entries[relPath] = content
616 } catch {
617 // Skip unreadable files
618 }
619 }
620 }),
621 )
622 } catch (e) {

Callers 1

pushTeamMemoryFunction · 0.85

Calls 5

getTeamMemPathFunction · 0.85
walkDirFunction · 0.85
keysMethod · 0.80
logForDebuggingFunction · 0.50
logEventFunction · 0.50

Tested by

no test coverage detected