[tab] /home/franz.srambical/test_extension/test/src/extension.ts (typescript)
import * as vscode from 'vscode'

let output: vscode.OutputChannel
let tracingEnabled = false

function isInWorkspace(uri: vscode.Uri): boolean {
    const folders = vscode.workspace.workspaceFolders
    if (!folders) return false
    return folders.some(f => uri.fsPath.startsWith(f.uri.fsPath))
}

function shouldIgnore(uri: vscode.Uri): boolean {
    const p = uri.fsPath

    // Ignore VS Code internals and extension noise
    if (p.includes(`${pathSep}.vscode${pathSep}`)) return true
    if (p.includes(`${pathSep}node_modules${pathSep}`)) return true
    if (p.includes(`${pathSep}.git${pathSep}`)) return true

    return false
}

const pathSep = require('path').sep

export function activate(context: vscode.ExtensionContext) {
    output = vscode.window.createOutputChannel('Edit Trace Probe')

    const log = (msg: string) => {
        if (!tracingEnabled) return
        output.appendLine(`[${new Date().toISOString()}] ${msg}`)
    }

    // ---- Commands ----
    context.subscriptions.push(
        vscode.commands.registerCommand('editTraceProbe.start', () => {
            tracingEnabled = true
            output.show(true)
            output.appendLine('--- TRACE STARTED ---')
        })
    )

    context.subscriptions.push(
        vscode.commands.registerCommand('editTraceProbe.stop', () => {
            output.appendLine('--- TRACE STOPPED ---')
            tracingEnabled = false
        })
    )

    context.subscriptions.push(
        vscode.commands.registerCommand('editTraceProbe.showOutput', () => {
            output.show(true)
        })
    )

    // ---- Text document changes ----
    context.subscriptions.push(
        vscode.workspace.onDidChangeTextDocument(event => {
            const uri = event.document.uri
            if (!isInWorkspace(uri)) return
            if (shouldIgnore(uri)) return

            log(
                `TEXT_CHANGE
  uri=${uri.toString()}
  version=${event.document.version}
  changes=${event.contentChanges.length}
  active=${vscode.window.activeTextEditor?.document === event.document}`
            )
        })
    )

    // ---- Document open ----
    context.subscriptions.push(
        vscode.workspace.onDidOpenTextDocument(doc => {
            const uri = doc.uri
            if (!isInWorkspace(uri)) return
            if (shouldIgnore(uri)) return

            log(
                `DOC_OPEN
  uri=${uri.toString()}
  version=${doc.version}
  language=${doc.languageId}`
            )
        })
    )

    // ---- Filesystem watcher (workspace only) ----
    const watcher = vscode.workspace.createFileSystemWatcher('**/*')
    context.subscriptions.push(watcher)

    watcher.onDidChange(uri => {
        if (!isInWorkspace(uri)) return
        if (shouldIgnore(uri)) return
        log(`FS_CHANGE uri=${uri.toString()}`)
    })

    watcher.onDidCreate(uri => {
        if (!isInWorkspace(uri)) return
        if (shouldIgnore(uri)) return
        log(`FS_CREATE uri=${uri.toString()}`)
    })

    watcher.onDidDelete(uri => {
        if (!isInWorkspace(uri)) return
        if (shouldIgnore(uri)) return
        log(`FS_DELETE uri=${uri.toString()}`)
    })
}