UNPKG

zephyr-agent

Version:
295 lines (206 loc) • 10.2 kB
# Zephyr Agent (Internal) <div align="center"> [Zephyr Cloud](https://zephyr-cloud.io) | [Zephyr Docs](https://docs.zephyr-cloud.io) | [Discord](https://zephyr-cloud.io/discord) | [Twitter](https://x.com/ZephyrCloudIO) | [LinkedIn](https://www.linkedin.com/company/zephyr-cloud/) <hr/> <img src="https://cdn.prod.website-files.com/669061ee3adb95b628c3acda/66981c766e352fe1f57191e2_Opengraph-zephyr.png" alt="Zephyr Logo" /> </div> **Internal Package** - The main internal package that provides the Zephyr agent for bundler plugins. This package contains the core functionality for deployment, asset management, and communication with Zephyr Cloud. > **Note**: This is an internal package used by other Zephyr plugins. It is not intended for direct use by end users. ## Overview The Zephyr Agent is the core engine that powers all Zephyr bundler plugins. It provides: - **Deployment Pipeline**: Handles the complete deployment workflow to Zephyr Cloud - **Asset Management**: Optimizes and manages build assets for edge distribution - **Authentication**: Manages secure communication with Zephyr Cloud services - **Build Context**: Provides build-time context and metadata for plugins - **Edge Communication**: Handles communication with Zephyr's edge network ## Architecture The agent is structured into several key modules: ### Authentication (`lib/auth/`) - Handles user authentication and authorization - Manages API tokens and session management - Provides WebSocket connections for real-time updates - Reads `ZE_SECRET_TOKEN` directly without persisting the environment secret - Exchanges `ZE_CI_TOKEN` once per CI identity using a persistent, inter-process locked access-token cache - Keeps credential cleanup scoped so concurrent deployment and application records remain intact See [CI Token Identity](../../docs/ci-token-identity.md) for token precedence, identity attribution, persistence, and concurrency invariants. ### Build Context (`lib/build-context/`) - Extracts build metadata and package information - Provides Git integration and repository context - Manages dependency resolution and parsing ### Deployment (`lib/deployment/`) - Implements deployment strategies for different CDN providers - Supports Cloudflare, Fastly, and Netlify deployment targets - Handles asset uploads and build stats publication ### Edge Actions (`lib/edge-actions/`) - Manages deployment operations on edge infrastructure - Handles snapshot creation and environment enabling - Coordinates asset uploads and build statistics ### HTTP Layer (`lib/http/`) - Provides HTTP client functionality with retries - Handles file uploads and API communication - Manages request/response lifecycle ## Usage by Plugins Public Zephyr plugins interact with the agent through well-defined APIs: ```typescript import { ZephyrAgent } from 'zephyr-agent'; // Initialize the agent const agent = new ZephyrAgent({ buildContext: buildInfo, assets: assetMap, }); // Deploy to Zephyr Cloud await agent.deploy(); ``` ## Dependencies The agent has minimal external dependencies: - **Core Dependencies**: Node.js built-ins and essential utilities - **Network**: HTTP client libraries for API communication - **File System**: Asset management and build context extraction - **Crypto**: Secure token management and validation ## Configuration Bundler plugins can infer application identity from Git and `package.json`, or load a strict project config from the bundler context: ```typescript import { defineConfig } from 'zephyr-agent'; export default defineConfig({ org: 'my-org', project: 'my-project', appName: 'my-app', remoteDependencies: { remote: 'zephyr:remote.remote-project.remote-org@latest', }, dependencyUrlMode: 'version', }); ``` Name the file `zephyr.config.ts`, `.mts`, `.cts`, `.js`, `.mjs`, or `.cjs`. Only `org`, `project`, `appName`, `remoteDependencies`, and `dependencyUrlMode` are valid. Config identity wins over Git inference, `appName` wins over the package name, and config remotes win by key over `package.json` `zephyr:dependencies`. `dependencyUrlMode: 'version'` keeps tag, environment, and workspace selection while embedding the resolved immutable version URLs in Module Federation configuration. The default `selector` mode preserves mutable tag and environment URLs. Environment identity overrides are not supported, and config loading never mutates `process.env`. The config is resolved once when a `ZephyrEngine` is created and is shared by every compiler participating in that application build. Restart the bundler after changing the file so an active `ApplicationContext` never changes identity between watch generations. ### Git Repository Requirements Git remains the richest source of version metadata. An explicit Zephyr config can replace remote-origin identity inference while retaining Git author, branch, commit, and tag metadata. #### Git Information Handling When Zephyr cannot find a Git repository with remote origin, it will: 1. **Automatic Package.json-Based Naming**: - Extract organization, project, and app names from your `package.json` - Use authenticated user's username as the organization for personal Zephyr org - Follow intelligent naming conventions based on package structure - No user prompts or environment variables required 2. **Enhanced Naming Logic**: - **Scoped packages** (`@scope/name`): project = scope, app = name - **With root package.json**: - If root is scoped (`@scope/name`): project = scope, app = current package name - Otherwise: project = root package name, app = current package name - **Fallback to directory name**: If no root package.json found, uses directory name as project - **Single package**: project = app = package name - **Organization**: Uses authenticated user's username (sanitized for URL safety) #### Example Scenarios ```bash # Recommended: Proper Git setup (required for CI) git init git remote add origin git@github.com:YOUR_ORG/YOUR_REPO.git git add . && git commit -m "Initial commit" npm run build # Works perfectly with full Git context # Local-only metadata mode (no commit yet) git init git remote add origin git@github.com:YOUR_ORG/YOUR_REPO.git npm run build # Works for local builds; CI still requires commit history # Automatic fallback (works seamlessly) # No git repository - uses package.json naming npm run build # Automatically determines naming from package.json # Examples of automatic naming: # package.json: { "name": "@my-company/my-app" } # → org: "jwt-username", project: "my-company", app: "my-app" # package.json: { "name": "my-project" } (no root package.json) # → org: "jwt-username", project: "my-project", app: "my-project" # package.json: { "name": "my-app" } (root package.json: { "name": "my-workspace" }) # → org: "jwt-username", project: "my-workspace", app: "my-app" # package.json: { "name": "my-app" } (root package.json: { "name": "@company/monorepo" }) # → org: "jwt-username", project: "company", app: "my-app" # package.json: { "name": "my-app" } (no root package.json found) # → org: "jwt-username", project: "current-directory-name", app: "my-app" # Special characters in username get sanitized: # Username: "Néstor López" → org: "n-stor-l-pez" ``` #### Why Git is Required Zephyr uses Git information to: - Determine organization and project structure - Track deployment versions and commits - Enable collaboration features - Provide proper deployment metadata Without Git, Zephyr cannot guarantee proper functionality, especially for: - Production deployments - Team collaboration - Version tracking - Rollback capabilities #### Package.json-Based Naming (Non-Git Environments) When Git is not available (e.g., AI coding tools, quick prototypes), Zephyr automatically extracts naming information from your `package.json` structure: **Automatic Organization Detection:** - Uses the authenticated user's name from your authentication token - Requires valid authentication to determine organization **Project and App Naming Logic:** 1. **Scoped Package** (`@company/app-name`): - Project: `company` (scope without @) - App: `app-name` 2. **Monorepo Structure** (root `package.json` exists): - If root is scoped (`@company/monorepo`): Project = `company`, App = current package name - Otherwise: Project = root package name, App = current package name - If no root package.json found: Project = current directory name, App = current package name 3. **Single Package**: - Project: Package name - App: Package name ## Internal APIs ### Build Context API ```typescript // Extract package.json information const packageInfo = await readPackageJson(projectRoot); // Get Git repository information const gitInfo = await getGitInfo(); // Parse Zephyr dependencies const deps = parseZephyrDependencies(packageJson); ``` ### Deployment API ```typescript // Upload assets to CDN await uploadAssets(assets, uploadStrategy); // Enable environment on edge await enableSnapshotOnEdge(snapshotId); // Upload build statistics await uploadBuildStats(buildStats); ``` ## Integration Points The agent integrates with: - **Bundler Plugins**: Receives build assets and metadata - **Zephyr Cloud**: Deploys assets and manages deployments - **CDN Providers**: Uploads assets to edge locations - **Git Providers**: Extracts repository and commit information ## Development For plugin developers working on Zephyr integrations: ```bash # Build the agent npm run build # Run tests npm run test # Development mode npm run dev ``` ## Security The agent implements several security measures: - **Token Management**: Secure storage and rotation of API tokens - **Encrypted Communication**: All API communication uses HTTPS/WSS - **Input Validation**: Validates all build inputs and configurations - **Access Control**: Role-based access to deployment operations ## Contributing This is an internal package. Contributions should be made through the main Zephyr plugins repository. Please read our [contributing guidelines](../../CONTRIBUTING.md) for more information. ## License Licensed under the Apache-2.0 License. See [LICENSE](LICENSE) for more information.