Skip to content

feat(mounts): add convenience helper for inline mounting storage objects#675

Merged
james-rl merged 6 commits intomainfrom
james/mount-os
Dec 15, 2025
Merged

feat(mounts): add convenience helper for inline mounting storage objects#675
james-rl merged 6 commits intomainfrom
james/mount-os

Conversation

@james-rl
Copy link
Copy Markdown
Contributor

@james-rl james-rl commented Dec 15, 2025

User description

Description

  • Adds the ability to write code like this:
import { RunloopSDK } from '@runloop/api-client-ts'

const runloop = new RunloopSDK()

// save the object
const storageObject = await runloop.storageObject.uploadFromFile(
  './my-file.txt', // local file reference
  'my-file.txt',   // location on the box
  { metadata: { project: 'demo' } },
)

// start a devbox with the object on the box
const devboxWithFile = await runloop.devboxes.create({
	name: 'devbox-with-file',
	mounts: [{ '/opt/my-app/my-file-on-box.txt' : storageObject}] // this is the change

Motivation

  • This makes it quite natural to provide a mount location for objects that use the storage mount. This came up during creation of a blog post: "Why can't I do this?"

Changes

  • This just adds sugar and convenient syntax to existing functionality; nothing new has been added here. It's also backwards compatible

Testing

  • Unit tests added
  • Integration tests added
  • Smoke Tests added/updated
  • Tested locally

Breaking Changes

This is a backwards compatible change

Checklist

  • PR title follows Conventional Commits format (feat: or feat(scope):)
  • Documentation updated (if needed)
  • Breaking changes documented (if applicable)

CodeAnt-AI Description

Support inline StorageObject mount syntax when creating Devboxes

What Changed

  • Devbox creation accepts a convenient mount form where a devbox path maps directly to a StorageObject (e.g., mounts: [{ '/path/on/devbox': storageObject }]) and automatically converts it to the API's object_mount format.
  • Existing mount formats continue to work unchanged; mixed arrays of inline mounts and standard mounts are supported.
  • Unit tests added to verify single/multiple inline mounts, mixed mount arrays, empty/null mounts, and that other devbox parameters and request options are preserved.

Impact

✅ Shorter devbox creation for attaching uploaded files
✅ Fewer mount format errors when using StorageObject mounts
✅ Clearer mount behavior verified by unit tests

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai bot commented Dec 15, 2025

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Dec 15, 2025
@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai bot commented Dec 15, 2025

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Unsafe property access
    In transformMounts the mapping converts inline mounts via Object.entries(mount).map(([path, obj]) => ({ object_id: obj.id, ... })) without validating obj. If a value is missing or not a StorageObject, obj.id will throw. Validate obj (and obj.id) and surface a clear error instead of letting a cryptic runtime exception occur.

  • Permissive type guard
    The isInlineObjectMount type guard treats any non-null object without a type property as an InlineObjectMount. This is too permissive: arrays, other objects, or malformed mounts could be misclassified. That may lead to runtime errors when the code assumes the object's values are StorageObject instances (with .id). Consider tightening the guard to exclude arrays and validate that values look like StorageObjects (e.g. have an id).

  • Type assertion / returning original params
    transformSDKDevboxCreateParams returns params as DevboxCreateParams when params.mounts is falsy or empty. This assertion may hide shape differences between SDKDevboxCreateParams and DevboxCreateParams. Prefer an explicit safe mapping or normalize mounts to the exact API shape (e.g. undefined or []) to avoid subtle mismatches.

  • Mocking strategy collision
    The file both calls jest.mock('../../src/sdk/devbox') and then uses jest.spyOn(Devbox as any, 'create'). Depending on how the module mock is created (manual mock vs auto-mock), spying may interact poorly with the mocked module shape. Verify that the spy is applied to the exported member that test code will call at runtime.

@github-actions
Copy link
Copy Markdown

⚠️ Object Smoke Tests & Coverage Report

Test Results

✅ All smoke tests passed

Coverage Results

Metric Coverage Required Status
Functions 99.27% 100%
Lines 86.45% - ℹ️
Branches 50% - ℹ️
Statements 84.59% - ℹ️

Coverage Requirement: 100% function coverage (all public methods must be called in smoke tests)

⚠️ Some object methods are not covered in smoke tests. Please add tests that call all public methods.

View detailed coverage report

Coverage reports are available in the workflow artifacts. Lines/branches/statements coverage is tracked but not required to be 100%.

📋 View workflow run

Comment thread tests/sdk/devbox-ops.test.ts Outdated
@@ -0,0 +1,345 @@
import { DevboxOps, SDKDevboxCreateParams, MountInstance, InlineObjectMount } from '../../src/sdk';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The InlineObjectMount symbol is imported from the SDK but never used in this test file, leaving dead code that can confuse readers and slightly increase maintenance overhead; it should be removed from the import list. [code quality]

Severity Level: Minor ⚠️

Suggested change
import { DevboxOps, SDKDevboxCreateParams, MountInstance, InlineObjectMount } from '../../src/sdk';
import { DevboxOps, SDKDevboxCreateParams, MountInstance } from '../../src/sdk';
Why it matters? ⭐

The file indeed imports InlineObjectMount at the top but never references that symbol anywhere in the test file. Removing the unused import is a small, safe cleanup that reduces cognitive noise and avoids an unused-symbol lint warning. This is a straightforward, correct improvement.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/sdk/devbox-ops.test.ts
**Line:** 1:1
**Comment:**
	*Code Quality: The `InlineObjectMount` symbol is imported from the SDK but never used in this test file, leaving dead code that can confuse readers and slightly increase maintenance overhead; it should be removed from the import list.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

@codeant-ai
Copy link
Copy Markdown
Contributor

codeant-ai bot commented Dec 15, 2025

CodeAnt AI finished reviewing your PR.

@github-actions
Copy link
Copy Markdown

⚠️ Object Smoke Tests & Coverage Report

Test Results

✅ All smoke tests passed

Coverage Results

Metric Coverage Required Status
Functions 99.27% 100%
Lines 86.45% - ℹ️
Branches 50% - ℹ️
Statements 84.59% - ℹ️

Coverage Requirement: 100% function coverage (all public methods must be called in smoke tests)

⚠️ Some object methods are not covered in smoke tests. Please add tests that call all public methods.

View detailed coverage report

Coverage reports are available in the workflow artifacts. Lines/branches/statements coverage is tracked but not required to be 100%.

📋 View workflow run

@github-actions
Copy link
Copy Markdown

⚠️ Object Smoke Tests & Coverage Report

Test Results

✅ All smoke tests passed

Coverage Results

Metric Coverage Required Status
Functions 98.55% 100%
Lines 84.9% - ℹ️
Branches 45.91% - ℹ️
Statements 83.33% - ℹ️

Coverage Requirement: 100% function coverage (all public methods must be called in smoke tests)

⚠️ Some object methods are not covered in smoke tests. Please add tests that call all public methods.

View detailed coverage report

Coverage reports are available in the workflow artifacts. Lines/branches/statements coverage is tracked but not required to be 100%.

📋 View workflow run

@james-rl james-rl requested a review from dines-rl December 15, 2025 21:17
@github-actions
Copy link
Copy Markdown

⚠️ Object Smoke Tests & Coverage Report

Test Results

✅ All smoke tests passed

Coverage Results

Metric Coverage Required Status
Functions 98.55% 100%
Lines 84.9% - ℹ️
Branches 45.91% - ℹ️
Statements 83.33% - ℹ️

Coverage Requirement: 100% function coverage (all public methods must be called in smoke tests)

⚠️ Some object methods are not covered in smoke tests. Please add tests that call all public methods.

View detailed coverage report

Coverage reports are available in the workflow artifacts. Lines/branches/statements coverage is tracked but not required to be 100%.

📋 View workflow run

Comment thread src/sdk.ts
* ]
* ```
*/
mounts?: Array<MountInstance> | null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move this stuff into other files outside of sdk.ts

@james-rl james-rl changed the title chore(mounts): add convenience helper for inline mounting storage objects feat(mounts): add convenience helper for inline mounting storage objects Dec 15, 2025
@james-rl james-rl merged commit 2e5866c into main Dec 15, 2025
9 checks passed
@james-rl james-rl deleted the james/mount-os branch December 15, 2025 22:14
@stainless-app stainless-app bot mentioned this pull request Dec 15, 2025
@dines-rl dines-rl mentioned this pull request Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants