refactor: replace Rust server with apps workspace#460
Merged
Conversation
Comment on lines
+251
to
+257
| const runnerResponse = await fetch(targetUrl, { | ||
| method: req.method, | ||
| headers: { | ||
| Authorization: `Bearer ${runner.apiKey}`, | ||
| Accept: req.header('accept') || 'text/event-stream', | ||
| }, | ||
| }) |
| } | ||
|
|
||
| export function generateApiKeyHash(value: string): string { | ||
| return crypto.createHash('sha256').update(value).digest('hex') |
| * Empty URLs are assumed to be Docker Hub. | ||
| */ | ||
| function normalizeRegistryUrl(url: string): string { | ||
| if (!url || url.trim() === '' || url.toLowerCase().includes('docker.io')) { |
| return DOCKER_HUB_URL | ||
| } | ||
| // Strip trailing slashes for consistent matching | ||
| return url.trim().replace(/\/+$/, '') |
|
|
||
| // Add default Docker Hub registry only if user doesn't have their own Docker Hub credentials | ||
| // The auth configs map is keyed by URL, so adding the default last would override user credentials | ||
| const userHasDockerHubCreds = sourceRegistries.some((registry) => registry.url.includes('docker.io')) |
Comment on lines
+279
to
+286
| await axios.delete( | ||
| `${this.configService.getOrThrow('oidc.issuer')}/api/v2/users/${authContext.userId}/identities/${provider}/${providerUserId}`, | ||
| { | ||
| headers: { | ||
| Authorization: `Bearer ${token}`, | ||
| }, | ||
| }, | ||
| ) |
| return [ | ||
| `\n\n${ind}// Run code securely inside the Sandbox`, | ||
| `${ind}const codeRunResponse = await sandbox.process.codeRun(\``, | ||
| `${(p.state['codeRunParams'].languageCode ?? '').replace(/`/g, '\\`').replace(/\$\{/g, '\\${')}`, // Escape backticks and ${ to prevent breaking the template literal |
| } | ||
|
|
||
| function escapePromiseSpecialCharacters(contents) { | ||
| return contents.replace(/`Promise`\s*\\<((?:`?[^`<>]+`?|<[^<>]+>)*?)>/g, (_match, typeContent) => { |
| type = indexSignatureType | ||
| } | ||
|
|
||
| type = type.replace(/([*_`\[\]()<>|])/g, '\\$1') |
| runCommands(...commands: (string | string[])[]): Image { | ||
| for (const command of commands) { | ||
| if (Array.isArray(command)) { | ||
| this._dockerfile += `RUN ${command.map((c) => `"${c.replace(/"/g, '\\\\\\"').replace(/'/g, "\\'")}"`).join(' ')}\n` |
|
|
||
| // Calculate how many bytes we can safely process | ||
| // We need to keep bytes that could potentially be the start of a prefix marker | ||
| let safeLen = buf.length |
| <TooltipTrigger asChild> | ||
| {labelCount > 0 ? ( | ||
| <div className="truncate w-fit bg-blue-100 rounded-sm text-blue-800 dark:bg-blue-950 dark:text-blue-200 px-1"> | ||
| {labelCount > 0 ? (labelCount === 1 ? '1 label' : `${labelCount} labels`) : '/'} |
| Updating... | ||
| </Button> | ||
| ) : ( | ||
| <Button type="submit" form="update-region-form" variant="default" disabled={loading || !hasChanges}> |
| className={cn({ | ||
| 'text-foreground': checked, | ||
| 'text-muted-foreground': !checked, | ||
| 'hover:underline': !checked && link, |
| }) | ||
| }} | ||
| aria-label="Select all" | ||
| disabled={!deletePermitted || loading} |
| checked={row.getIsSelected()} | ||
| onCheckedChange={(value) => row.toggleSelected(!!value)} | ||
| aria-label="Select row" | ||
| disabled={!deletePermitted || loadingSnapshots[row.original.id] || loading} |
| if (!isOpen) setRegionToUpdate(null) | ||
| }} | ||
| onUpdateRegion={handleUpdateRegion} | ||
| loading={regionToUpdate ? regionIsLoading[regionToUpdate.id] || false : false} |
| return cleanedContent | ||
| } | ||
|
|
||
| return modified ? lines.join('\n') : contents |
| const countText = count === 1 ? 'this volume' : `these ${count} selected volumes` | ||
|
|
||
| return ( | ||
| <AlertDialog open={action !== null} onOpenChange={(open) => !open && onCancel()}> |
Contributor
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
| if err != nil { | ||
| return "", fmt.Errorf("error opening profile file (%s): %s", profilePath, err) | ||
| } | ||
| defer profile.Close() |
| if err != nil { | ||
| logger.Error("Failed to open log file", "path", c.DaemonLogFilePath, "error", err) | ||
| } else { | ||
| defer logFile.Close() |
| if err != nil { | ||
| return common_errors.NewInternalServerError(fmt.Errorf("failed to open input pipe: %w", err)) | ||
| } | ||
| defer f.Close() |
| if err != nil { | ||
| s.logger.Debug("failed to open log file to echo input", "error", err) | ||
| } else { | ||
| defer logFile.Close() |
| if err != nil { | ||
| return err | ||
| } | ||
| defer out.Close() |
| log.Errorf("Failed to open log file for %s: %v", process.Name, err) | ||
| } else { | ||
| process.cmd.Stdout = logFile | ||
| defer logFile.Close() |
| log.Errorf("Failed to open error file for %s: %v", process.Name, err) | ||
| } else { | ||
| process.cmd.Stderr = errFile | ||
| defer errFile.Close() |
| if err != nil { | ||
| return fmt.Errorf("failed to create host key file: %w", err) | ||
| } | ||
| defer privateKeyFile.Close() |
f24885d to
82a375b
Compare
82a375b to
fba3bb9
Compare
2 tasks
lilongen
pushed a commit
to lilongen/boxlite
that referenced
this pull request
Jun 8, 2026
apps/api/src/user/user.service.ts has imported `node-forge` (SSH key PEM → OpenSSH conversion) since boxlite-ai#460 (the Rust-server → apps-workspace migration), but the package was never a declared dependency on main. An earlier branch commit (a946f7c) declared it, then d86eb14 dropped it again as an "unrelated dep change" on the assumption that main resolves node-forge transitively. That assumption no longer holds: nothing in the resolved tree depends on node-forge (yarn why shows no transitive path), so webpack fails to resolve the import and `nx serve api` won't build locally. Root cause is the same as the typeorm drift — apps/yarn.lock is gitignored, so a floating range that once hoisted node-forge no longer does. A directly-imported package must be a direct dependency, not rely on transitive hoisting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lilongen
pushed a commit
to lilongen/boxlite
that referenced
this pull request
Jun 9, 2026
apps/api/src/user/user.service.ts has imported `node-forge` (SSH key PEM → OpenSSH conversion) since boxlite-ai#460 (the Rust-server → apps-workspace migration), but the package was never a declared dependency on main. An earlier branch commit (a946f7c) declared it, then d86eb14 dropped it again as an "unrelated dep change" on the assumption that main resolves node-forge transitively. That assumption no longer holds: nothing in the resolved tree depends on node-forge (yarn why shows no transitive path), so webpack fails to resolve the import and `nx serve api` won't build locally. Root cause is the same as the typeorm drift — apps/yarn.lock is gitignored, so a floating range that once hoisted node-forge no longer does. A directly-imported package must be a direct dependency, not rely on transitive hoisting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 tasks
G4614
added a commit
to G4614/boxlite
that referenced
this pull request
Jun 10, 2026
The SST production webpack build (apps/api/Dockerfile → nx build api --configuration=production) has been silently broken on main. No CI step runs this path, and e2e uses ts-node --transpile-only, so two structural issues went unnoticed since boxlite-ai#460: 1. webpack.config.js registers each migration file as a webpack entry using the cwd-relative path returned by glob.sync (e.g. "apps/api/src/ migrations/<X>-migration.ts"). Webpack resolves entry values against config.context, which @nx/webpack sets to the project root ("/boxlite/apps/api"), producing "/boxlite/apps/api/apps/api/src/...". Result: 91 "Module not found" errors. Fix: map each match through path.resolve(process.cwd(), ...) so entries are absolute. 2. The Dockerfile copies apps/tsconfig.base.json to /boxlite/ but apps/api/tsconfig.json extends "../tsconfig.base.json", resolving to /boxlite/apps/tsconfig.base.json. Result: TS5083 missing-tsconfig. Fix: split the COPY so tsconfig.base.json lands at apps/tsconfig.base.json. These two fixes are the bare minimum to get the prod webpack build past its structural blockers. The build now reaches tsc and surfaces a pre-existing class of 163 type errors (Express 5 ParamsDictionary widening + an OTel dep duplication + a libs/ link gap) — those are a separate concern and will be addressed in follow-up PRs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 10, 2026
DorianZheng
added a commit
that referenced
this pull request
Jun 10, 2026
…wagger spec (#721) ## Summary Closes out the **analytics-api-client** item of #711 (Sandbox→Box Part 1 follow-ups). #706 renamed the dashboard's analytics consumers to Box-named symbols (`ModelsBoxUsage`, `organizationOrganizationIdUsageBoxGet`, …) but the committed client still only exported Sandbox-named ones — the dashboard could not typecheck against the in-repo client. The client also couldn't be regenerated from this repo at all: its generator input was an uncommitted `tmp/swagger.json` from the external analytics service (the reason #716 excluded it). ## Changes - **Commit the contract in-repo**: `apps/libs/analytics-api-client/swagger.json`, reconstructed 1:1 from the previously committed client with only sandbox→box renamed (paths `/organization/{organizationId}/box/{boxId}/…`, `models.BoxUsage`, `boxId`, `boxCount`). This is now the spec any future analytics service must implement — same spec-first direction as `openapi/box.openapi.yaml`. - **Point `generate:api-client` at it** (`project.json`), with nx cache inputs tracking the spec instead of the unrelated `apiClient` named input. - **Regenerate** with the pinned openapi-generator **7.23.0** (committed client was stale 7.12.0 output — the last client on the old generator). Zero `sandbox` tokens remain. - **Drift gate**: drop the analytics exclusion from `api-client-drift.yml` — it now regenerates + diffs analytics like the other clients (actionlint clean). - **eslint**: ignore `**/.nx/**` — the generate target caches its `src/` output under the gitignored `apps/.nx/cache`, and lint after a local regen tripped on the cached copy of generated code. ## Verification - Two-side dashboard typecheck: against the **old** client → 13 rename-mismatch errors (`'ModelsBoxUsage'… Did you mean 'ModelsSandboxUsage'?`); against the **new** client → **zero** analytics-related errors (remaining 24 are pre-existing, unrelated: Playground/VNC files + unbuilt `@boxlite-ai/sdk` dist). - Regen is byte-identical across runs (`--skip-nx-cache`), so the drift gate won't false-positive. - `make lint:apps` exit 0. ## Notes - Runtime risk is nil: the analytics client is only instantiated when `ANALYTICS_API_URL` is configured, no analytics service exists in the org today, and the API's own (already-renamed) `box/:boxId/telemetry/*` endpoints serve the dashboard otherwise (`AnalyticsApiDisabledGuard` makes the two mutually exclusive). - Pre-existing, **not** fixed here (scope): `apps/dashboard/tsconfig.app.json` path mappings (`\"@boxlite-ai/*\": [\"../../libs/*\"]`) have pointed outside the workspace since the apps tree was flattened (#460), so raw `tsc -p` never resolved any `@boxlite-ai/*` import. Worth its own follow-up. Part of #711. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AWS Signature V4 support for API requests. * Telemetry and usage endpoints now operate at box (per-box) and organization levels (replacing sandbox-level variants). * **Documentation** * Comprehensive API docs added/updated with examples for box telemetry, per-box usage, aggregated usage, and usage chart endpoints. * **Chores** * Drift detection updated to include the analytics API client; linting ignores extended for generated files. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: dorianzheng <xingzhengde72@gmail.com>
G4614
added a commit
that referenced
this pull request
Jun 12, 2026
Merging the substantive bits of #745 and #746 here so PR #724's deploy-app-services CI can actually push an otel-collector image: * otel-collector/builder-config.yaml: fix module paths after #730 moved everything under apps/ (was: ../../../api-client-go etc., now: ../../../apps/api-client-go). The OCB build was failing with `filepath does not exist: /boxlite/otel-collector/exporter`. (#745) * otel-collector/Dockerfile: apk add python3 make g++ so node-gyp can compile any musl-incompatible native add-on during workspace `yarn install`. Kept even after dropping dockerode below — small safety net in case future deps reintroduce a native build. (#745) * apps/package.json: drop unused dockerode + @types/dockerode. They were inherited from the Daytona import in #460 but never imported in source. Drops the dockerode -> docker-modem -> ssh2 -> cpu-features chain; cpu-features was the optional native addon that forced the toolchain workaround in the first place. (#746) * apps/yarn.lock: regenerated (-161 lines). * apps/api-client-go/api/openapi.yaml: regenerate to catch up with main's existing `assignedRoleIds.default: []` drift so the api-client-drift PR check passes.
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.
Summary
boxlite-servercrate from the Cargo workspace and Make targetsgo.workTests
git diff --cached --checkcargo metadata --locked --no-depscargo fmt --all -- --checkBOXLITE_DEPS_STUB=1 cargo check --workspace --all-targets --all-features --exclude boxlite-guestfor dir in apps/api-client-go apps/cli apps/common-go apps/daemon apps/libs/computer-use apps/otel-collector/exporter apps/proxy apps/runner apps/snapshot-manager apps/ssh-gateway; do (cd "$dir" && go test -tags boxlite_dev ./...); done