@promptshield/workspace
v1.0.2
Published
Helper functions for loading workspace files. Shared by CLI and LSP
Maintainers
Readme
@promptshield/workspace
High-performance workspace scanning engine for PromptShield. Manages filesystem traversal, layered ignore resolution (.gitignore, .promptshieldignore, .psignore), concurrency, and caching while delegating detection to @promptshield/core and inline directive processing to @promptshield/ignore.
✨ What This Package Does
@promptshield/workspace is responsible for:
- Workspace file resolution
- Binary detection
- Concurrent file scanning
- Cache orchestration
- Severity filtering
- Markdown report generation
It does not implement detection logic — that lives in @promptshield/core.
It does not implement Inline ignore processing (Delegated to @promptshield/ignore)
📦 Installation
$ pnpm add @promptshield/workspaceor
$ npm install @promptshield/workspaceor
$ yarn add @promptshield/workspaceBasic Workspace Scan
import { scanWorkspace } from "@promptshield/workspace";
const root = process.cwd();
const patterns = ["**/*.ts", "**/*.js"];
for await (const { path, result, progress } of scanWorkspace(patterns, root)) {
console.log(
`[${progress}%] ${path} → ${result.threats.length} active threats`
);
}Streaming. Concurrency-bounded. Memory safe.
🧠 How Scanning Works
Execution Model
- Files are resolved using layered ignore rules.
- Scanning runs concurrently (default: 4 files).
- Results are yielded progressively via Async Generator.
- Output order matches task creation order.
⚙️ Configuration
scanWorkspace(patterns, root, {
minSeverity: "MEDIUM",
noInlineIgnore: false,
concurrency: 8,
cacheMode: "auto",
forceFullScan: false,
});Configuration Reference
minSeverity
Minimum severity to report.
When caching is enabled:
- Baseline scan always runs with
"LOW" - Severity filtering is applied after cache retrieval
Default: "LOW"
noInlineIgnore
Disables promptshield-ignore inline directives.
Does NOT affect:
.gitignore.promptshieldignore.psignore
Default: false
concurrency
Maximum files processed in parallel.
Default: 4
cacheMode
"none"→ no persistent cache"single"→ one cache file"split"→ per-file hashed cache"auto"→ strategy selected based on repo size
Default: "auto"
forceFullScan
Clears cache and rescans everything.
Default: false
💾 Cache Semantics (Important)
When caching is enabled:
Baseline scan always uses:
minSeverity: "LOW"- Inline ignore enabled
Results are cached post-filtering
Presentation-level filtering happens after retrieval
Cache writes are intentionally fire-and-forget.
Persistence must never block scan throughput.
📚 Deep Dives: For advanced explanations of how memory is managed during streaming, and exactly how caching locks and migration work, see the Documentation section.
📄 Generate Workspace Report
import { generateWorkspaceReport } from "@promptshield/workspace";
await generateWorkspaceReport(rootPath, allThreats, totalThreatCount);Generates:
<workspaceRoot>/.promptshield/workspace-report.mdReport includes:
- Timestamp
- Total threat count
- Affected files
- Grouped threats by line
- Editor-compatible
file://links
Report is generated only if threats exist.
🔍 Binary File Handling
Binary files are automatically skipped using:
- NULL-byte detection
- Suspicious byte ratio heuristic
Prevents false positives in:
- Images
- PDFs
- Archives
- Office documents
🏗 Architecture Role
Used by:
@promptshield/cli@promptshield/lsp
Ensures identical scanning semantics across environments.
🧩 Design Principles
- Deterministic output
- Streaming-first
- Cache-aware
- Editor-friendly
- Fail-safe behavior
📚 Documentation
- API reference: auto-generated
- Conceptual guides:
/docs/workspace - Recommended:
/docs/workspace/quick-start
📄 License
MIT
