Merge dev with main#347
Merged
IonesioJunior merged 235 commits intomainfrom Apr 1, 2026
Merged
Conversation
Add two major features on top of main's architecture: - API Tokens: CRUD endpoints, dual auth (JWT + API token), frontend settings tab, Python/TypeScript SDK support, comprehensive test coverage - NATS Tunneling: peer token auth, Redis client, NATS transport for aggregator, tunneling URL validation, WebSocket proxy config, heartbeat support - syfthub-api: complete package with HTTP/NATS server modes, heartbeat manager, policy enforcement, and full test suite
…and integration test commands
backend/uv.lock was gitignored, causing CI to resolve dependencies fresh and install ruff 0.15.0 instead of the pinned 0.14.14. This led to formatting check failures due to formatting differences between ruff versions. All other project lockfiles (aggregator, sdk/python, syfthub-api, mcp) were already tracked.
Resolves merge conflicts by preserving both: - Message history support for multi-turn context (from main) - NATS peer token tunneling support (from dev) Also adds MODEL_DATA_SOURCE to SDK's EndpointType enum for type matching.
Resolves merge conflicts in SDK files by combining: - User Aggregators feature (from main) - API Tokens, NATS, Heartbeat features (from dev) Both Python and TypeScript SDKs now include all features.
- Resolved pyproject.toml conflict by keeping all dependencies: * redis[hiredis] and nats-py from dev branch * google-auth from main branch - Fixed TypeScript type errors in Google OAuth components: * Added CredentialResponse type import to login-modal.tsx * Added CredentialResponse type import to register-modal.tsx * Fixed implicit 'any' type on callback parameters Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolves merge conflicts while preserving both: - Dev features: redis[hiredis] and nats-py dependencies - Main fix: google-auth[urllib3] transport for auth service Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sync main into dev
Sync main into dev
Resolved conflicts: - Makefile: Combined test targets from both branches (test, test-serial, test-integration), added syfthub-api and TypeScript SDK tests - aggregator/services/retrieval.py: Kept both AsyncIterator import and TYPE_CHECKING import, combined peer_channel parameter with return type Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nd extract_tunnel_username
…e schema Update generated Wails bindings and SettingsModal to use the new snake_case field names (hub_url, api_token, endpoints_path, is_configured, container_enabled, etc.). Add container_runtime and container_image to the Settings TypeScript class.
Add build_local() function that compiles the CLI from source when invoked from the repo root or cli/ directory. Works alongside the existing release-download path; callers can opt in via the SYFT_LOCAL_BUILD env var or by passing --local.
When no API token is configured, `syft node init` opens the user's browser to /cli-setup, waits on a local HTTP callback server (random port, CSRF state param), and receives the token automatically once the user authenticates. - cli: browser_auth.go — local callback server + cross-platform browser launcher; 5-minute timeout; CSRF state validation - cli: root.go — PersistentPreRunE ensureAuthenticated middleware with authExemptKey annotation so login/logout/add/etc. bypass the check - cli: nodeconfig — NodeKeyFile constant + fix aggregator URL path - frontend: /cli-setup page — standalone (no nav/sidebar), handles login, register, OTP verification, token creation, and redirect back to the waiting CLI process - frontend: extract getPasswordStrengthInfo to validation.ts (used by cli-setup, register-modal, and security-settings-tab)
- promptEndpointSetup: when endpoints dir is empty, presents a TUI
picker (charmbracelet/huh) to install from the marketplace, add a
custom endpoint, or skip — replaces the old promptWithDefault flow
- killOrphanedNodes: terminates stale "syft node run" processes that
accumulate after force-stop/crash and cause DECRYPTION_FAILED errors
from duplicate NATS subscribers
- force-kill after graceful shutdown window if the process is still alive
- minor: map[string]interface{} → map[string]any throughout
Date instances were falling through to the object branch in convertDates, which enumerated their (empty) own properties and lost the value. The new instanceof Date guard converts them to ISO strings first, then the existing parse-dates path converts them back to Date when parseDates is true.
Gate create/update/delete/upload routes behind MARKETPLACE_ADMIN_TOKEN. Use crypto/subtle for constant-time comparison to prevent timing attacks. Startup exits if token is unset.
Add env var to docker-compose (dev + prod), pass secret through CI deploy steps, and persist to .env with update-or-append (matching NGROK pattern).
Run go test for cli, syfthub-desktop, and sdk/golang/syfthubapi now that test coverage lives in Go instead of pytest.
Add tests for API container factory/cleanup hooks, config defaults and env loading for container vars, containermode cleanup/executor/runtime edge cases, and marketplace FetchPackages error paths.
Add tests for new default fields (Timeout, LogLevel, ContainerEnabled), snake_case JSON serialization for all settings fields, and ConfigInfo JSON roundtrip.
New tests for agent, browser-auth, node-init, and root commands, plus comprehensive nodeconfig config loading tests.
Merge main into dev, resolving conflicts: - security.py: combine both sets of imports (time from dev + base64/hashlib/logging from main) - main.py lifespan: keep OTPCleanupJob from dev + improved httpx client config from main - main.py proxy: keep dev's test-friendly fallback pattern for http_client
- Migrate websocket import from nhooyr.io/websocket to github.com/coder/websocket - Remove unused listResults field from mockContainerRuntime in api_test.go - Replace deprecated SlogLogger wrapper with direct *slog.Logger in http_test.go
The CLI module uses a replace directive to the local SDK, which now imports github.com/coder/websocket instead of nhooyr.io/websocket.
go mod tidy updated go.mod to add github.com/coder/websocket and remove nhooyr.io/websocket, but only go.sum was committed previously.
Fix Makefile ldflags path (cli-go → cli) so local builds inject version correctly. Add pre-release detection to release workflow (marks beta/alpha/rc as GitHub pre-releases). Rewrite version comparison to be semver-aware with proper pre-release ordering. Stable users are never prompted to upgrade to beta; beta users get updates within the pre-release channel. Update install script to skip pre-release tags by default.
…ation
syscall.SysProcAttr{Setsid: true} does not exist on Windows, breaking
the release workflow. Extract into sysproc_unix.go (Setsid) and
sysproc_windows.go (CREATE_NEW_PROCESS_GROUP) with build tags.
# Conflicts: # components/backend/pyproject.toml # components/backend/src/syfthub/api/endpoints/accounting.py # components/backend/src/syfthub/auth/router.py # components/backend/src/syfthub/core/config.py # components/backend/src/syfthub/domain/exceptions.py # components/backend/src/syfthub/observability/handlers.py # components/backend/src/syfthub/repositories/user.py # components/backend/src/syfthub/services/auth_service.py # components/frontend/src/components/auth/register-modal.tsx # components/frontend/src/context/auth-context.tsx # sdk/typescript/src/client.ts # sdk/typescript/src/resources/auth.ts
Delete the marketplace package registry service and all references:
- components/marketplace/ — Go service (11 files)
- sdk/golang/syfthubapi/nodeops/marketplace.go — SDK client + tests
- cli/internal/cmd/node_marketplace.go — CLI `node marketplace` command
- cli/internal/cmd/node_init.go — interactive marketplace picker in `node init`
- cli/internal/nodeconfig/config.go — MarketplaceURL config field
- .github/workflows/ci.yml — Docker build matrix + MARKETPLACE_ADMIN_TOKEN deploy steps
- deploy/docker-compose.{dev,deploy}.yml — service definition, volumes, depends_on
- deploy/nginx/nginx.{dev,prod}.conf — upstream + location blocks
| from alembic import op | ||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = "004_email_otp" |
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = "004_email_otp" | ||
| down_revision: str | None = "003_encryption_key" |
| # revision identifiers, used by Alembic. | ||
| revision: str = "004_email_otp" | ||
| down_revision: str | None = "003_encryption_key" | ||
| branch_labels: str | Sequence[str] | None = None |
| revision: str = "004_email_otp" | ||
| down_revision: str | None = "003_encryption_key" | ||
| branch_labels: str | Sequence[str] | None = None | ||
| depends_on: str | Sequence[str] | None = None |
| from alembic import op | ||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = "005_otp_requester_ip" |
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = "005_otp_requester_ip" | ||
| down_revision: str | None = "004_email_otp" |
| # revision identifiers, used by Alembic. | ||
| revision: str = "005_otp_requester_ip" | ||
| down_revision: str | None = "004_email_otp" | ||
| branch_labels: str | Sequence[str] | None = None |
| revision: str = "005_otp_requester_ip" | ||
| down_revision: str | None = "004_email_otp" | ||
| branch_labels: str | Sequence[str] | None = None | ||
| depends_on: str | Sequence[str] | None = None |
| # revision identifiers, used by Alembic. | ||
| revision: str = "006_json_to_jsonb" | ||
| down_revision: str | None = "003_encryption_key" | ||
| down_revision: str | None = "005_otp_requester_ip" |
| await otp_cleanup.stop() | ||
| otp_cleanup_task.cancel() | ||
| with contextlib.suppress(asyncio.CancelledError): | ||
| await otp_cleanup_task |
Check and propagate errors from closing the writable log file handle in both the error path (cmd.Start failure) and success path.
Handle errors from f.Write() and f.Close() in the request logging function instead of silently dropping them.
Only the setter setInitialPrompt is used; the value itself is never read. Destructure without the binding to satisfy the lint rule.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces several improvements to CI/CD workflows, adds a new release pipeline for the SyftHub Desktop app, and enhances test coverage and environment management. The most significant changes are grouped below.
CI/CD Workflow Improvements
RESEND_API_KEYin deployment jobs and ensuring it is included in the.envfile for Docker Compose deployments. (.github/workflows/ci.yml) [1] [2] [3] [4]Release Automation Enhancements
Developer Experience and Testing
Makefileto expand Go test coverage for the CLI, desktop app, and Go SDK, improving test reliability and coverage reporting. (Makefile)app.shhelper script to streamline building, running, and cleaning the SyftHub Desktop app locally, making development and testing easier. (app.sh)