Architecture Overview

June 28, 2026 · View on GitHub

This document outlines the major components inside SecureZip so you can quickly find the right files when adding features or debugging.

Entry point and commands

  • src/extension.ts is the activation entry. It registers commands declared in package.json:
    • securezip.export – orchestrates the plain export workflow (progress UI, .securezipignore loading, archiver, git tagging/commits).
    • securezip.exportWorkspace – plain export for the multi-root workspace.
    • securezip.exportEncrypted / securezip.exportWorkspaceEncrypted – the same workflows wrapped with the password prompt described under Encrypted export.
    • securezip.addToIgnore, securezip.addPattern, securezip.applySuggestedPatterns – helpers that modify ignore rules.
    • securezip.openIgnoreFile, securezip.createIgnoreFile – file utilities.
  • archiver handles ZIP creation; simple-git performs auto-commit/tag operations.
  • Feature flags come from src/flags.ts, mixing build-time defines (__BUILD_FLAGS__ via esbuild.js) and runtime settings.

Encrypted export pipeline

  • The exportEncrypted / exportWorkspaceEncrypted commands reuse the regular export flow but inject a ZipCreationOptions of { mode: 'encrypted', password } after a two-step prompt (promptEncryptedZipPassword). Cancellation at either step returns undefined and short-circuits the command before any file is written.
  • Encryption is provided by archiver-zip-encrypted registered as the zip-encrypted archiver format with encryptionMethod: 'aes256'. The format is registered lazily via ensureZipEncryptedFormatRegistered, which guards against archiver's "format already registered" error when the user runs multiple encrypted exports in one session.

Failure semantics

createZipEntries writes to a temporary .<basename>.<pid>-<rand>.partial in the destination directory and renames it onto the final path on success.

  • The export entry list excludes the destination archive itself and any SecureZip temp archives matching .<basename>.<pid>-<rand>.partial, so stale replacement files cannot be embedded into later exports. Destination archive filtering uses normalized paths and file identity when available.
  • If the destination archive already exists, its permission bits are applied to the temporary archive on a best-effort basis before the rename.
  • If writeArchiveToFile fails, the temp file is removed via cleanupTempArchive and the original error is re-thrown. Any pre-existing ZIP at the destination is untouched because the rename never runs.
  • If the rename itself fails, the temp file is removed for the same reason and the original ZIP is preserved.
  • The Git auto-commit and tag steps run before the archive is written, so a failure inside createZipEntries (or during password prompting) can leave newly-created commits/tags in the repository. This is documented for users in the README; downstream tooling should assume Git side-effects may persist even when the ZIP is missing.

Concurrency lock

runExportCommandWithLock wraps every export command. It maintains a single process-wide isExportRunning boolean: when a command starts it flips the flag to true; a second invocation that arrives while the flag is set surfaces a warning (warning.exportAlreadyRunning) and returns immediately without running the wrapped task. The flag is cleared in a finally block so an exception in the inner task always releases the lock.

Ignore and exclude handling

  • src/ignore.ts parses .securezipignore, persists patterns, and exposes helpers used by both the export command and the tree view.
  • src/defaultExcludes.ts + src/autoExcludeDisplay.ts describe the built-in auto-exclude set (git metadata, node_modules, etc.) and the metadata displayed in the preview.
  • Suggested patterns and duplicates are surfaced through these modules.

SecureZip view

  • src/view.ts implements SecureZipViewProvider, a TreeDataProvider that renders sections for the guide, actions, .securezipignore preview, and recent exports.
  • The preview section highlights auto excludes, re-includes, duplicates, and .gitignore-sourced patterns with tooltip/context information. Displayed entries are deduplicated by priority: .securezipignore > .gitignore > auto-excludes. Suppressed sources are listed in the tooltip (“Also excluded by …”), and unmatched/comment lines are omitted to reduce noise. Match counts for .securezipignore rules and .gitignore patterns live only in tooltips to keep labels minimal.
  • The view listens for file system changes, git events, and command results to keep the tree in sync.

Localization

  • Runtime strings use localize from src/nls.ts, which loads bundles from i18n/nls.bundle.<lang>.json.
  • Contribution strings in package.json pull from package.nls*.json.
  • See docs/localization.md for instructions on adding new keys/translations.

Build tooling

  • esbuild.js bundles the extension into dist/extension.js. Production builds (npm run package) enable minification, inject build flags, and emit SBOM metadata by running scripts/generate-sbom.cjs.
  • Type declarations are handled by tsc (no emit) during check-types and via tsc -p . --outDir out for the test harness.

Tests

  • Unit tests live under src/test/ and target individual helpers (flags, ignore parser, preview ordering, etc.).
  • Integration tests run through @vscode/test-electron (npm run test) to assert that the SecureZip view behaves correctly inside VS Code.
  • Refer to docs/testing.md for the recommended workflows.

File map

PathResponsibility
src/extension.tsActivation, commands, export workflow
src/view.tsTree view provider / UI
src/ignore.ts.securezipignore parsing and persistence
src/defaultExcludes.tsDefault ignore templates
src/autoExcludeDisplay.tsPresentation logic for auto excludes
src/flags.tsFeature flag resolver
scripts/generate-sbom.cjsSBOM generation post-build

Keeping these boundaries in mind helps maintain a clear separation between UI, business logic (ignore/export), and tooling (build/test/release pipelines).