Skip to content

Conversation

@yosiwizman
Copy link

No description provided.

Yosi Wizman and others added 10 commits January 5, 2026 14:08
- Update package name and description
- Update page title and meta description
- Update UI placeholder text and header logo
- Update AI system prompt identity
- Update favicon and icons
- Update README with attribution
- Update GitHub issue templates
- Add .gitattributes for LF enforcement

Co-Authored-By: Warp <agent@warp.dev>
Co-Authored-By: Warp <agent@warp.dev>
- Add deploy-staging.yml for Cloudflare Pages deployment
- Add CI status badge to README
- Add staging URL and deployment documentation
- Add development setup instructions

Co-authored-by: Yosi Wizman <yosi@example.com>
Co-authored-by: Warp <agent@warp.dev>
* ci: add staging deployment workflow and update README

- Add deploy-staging.yml for Cloudflare Pages deployment
- Add CI status badge to README
- Add staging URL and deployment documentation
- Add development setup instructions

Co-Authored-By: Warp <agent@warp.dev>

* docs: update README with production status and release process

- Change staging to production status
- Add live URL designation
- Add release process documentation
- Document safeguards

Co-Authored-By: Warp <agent@warp.dev>

---------

Co-authored-by: Yosi Wizman <yosi@example.com>
Co-authored-by: Warp <agent@warp.dev>
- Add public/_headers with COOP/COEP headers for Cloudflare Pages
- Update entry.server.tsx to use credentialless COEP
- Add COOP/COEP headers to Cloudflare Pages function
- Add COOP/COEP headers to Vite dev server
- Add crossOriginIsolated verification warning in root.tsx
- Document cross-origin isolation in README

Headers:
- Cross-Origin-Opener-Policy: same-origin
- Cross-Origin-Embedder-Policy: credentialless

Co-authored-by: Yosi Wizman <yosi@example.com>
Co-authored-by: Warp <agent@warp.dev>
- Add publish.ts store for state management
- Add api.publish.ts API endpoint for Cloudflare Pages deployment
- Add PublishButton.client.tsx UI component
- Update README with publish feature documentation

Co-authored-by: Yosi Wizman <yosi@example.com>
Co-authored-by: Warp <agent@warp.dev>
- Use empty strings as manifest values (per CF API spec)
- Use file paths with leading slash as FormData field names
- Add getContentType helper for proper MIME types
- Remove unused hashContent function

Co-Authored-By: Warp <agent@warp.dev>
- Use empty strings as manifest values (per CF API spec)
- Use file paths with leading slash as FormData field names
- Add getContentType helper for proper MIME types
- Remove unused hashContent function

Co-authored-by: Yosi Wizman <yosi@example.com>
Co-authored-by: Warp <agent@warp.dev>
Co-Authored-By: Warp <agent@warp.dev>
Copilot AI review requested due to automatic review settings January 6, 2026 01:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR rebrands "Bolt" to "X Builder" and implements an MVP publish feature that deploys projects to Cloudflare Pages via the Direct Upload API. The changes include cross-origin isolation headers (COOP/COEP) required for WebContainers, CI/CD workflows for automated deployment, and comprehensive documentation updates.

Key changes:

  • Complete rebrand from "Bolt" to "X Builder" across all user-facing text and branding assets
  • New publish API endpoint (/api/publish) for deploying to Cloudflare Pages
  • Cross-origin isolation headers configured across all entry points to enable SharedArrayBuffer support
  • GitHub Actions workflows for CI and staging deployment

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
wrangler.toml Updates worker name from "bolt" to "x-builder"
vite.config.ts Adds COOP/COEP headers to development server
public/favicon.svg Updates branding from lightning bolt to "X" logo
public/_headers Adds COOP/COEP headers for Cloudflare Pages
package.json Updates project metadata and adds smoke test script
icons/logo.svg Updates branding to match new favicon
functions/[[path]].ts Wraps Remix handler to inject COOP/COEP headers
app/routes/api.publish.ts New API endpoint for Cloudflare Pages deployment
app/routes/_index.tsx Updates page title and meta description
app/root.tsx Adds crossOriginIsolated verification check
app/lib/stores/publish.ts New state management for publish functionality
app/lib/.server/llm/prompts.ts Updates AI assistant name in system prompt
app/entry.server.tsx Changes COEP from require-corp to credentialless
app/components/workbench/PublishButton.client.tsx New UI component for publishing projects
app/components/sidebar/Menu.client.tsx Removes unused IconButton import
app/components/header/Header.tsx Replaces logo with text branding
app/components/chat/BaseChat.tsx Updates chat placeholder text
README.md Complete rewrite with X Builder documentation
.github/workflows/deploy-staging.yml New deployment workflow for Cloudflare Pages
.github/workflows/ci.yml New CI workflow for linting and testing
.github/ISSUE_TEMPLATE/config.yml Updates issue template links
.github/ISSUE_TEMPLATE/bug_report.yml Updates references to X Builder
.gitattributes New file enforcing LF line endings

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* - A "manifest" field containing JSON object mapping file paths to empty strings
* - Individual file fields where field name is the file path and value is file content
*/
export async function action({ context, request }: ActionFunctionArgs) {
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The publish API endpoint has no authentication or rate limiting. Any user can publish unlimited projects to your Cloudflare account, potentially incurring costs or resource exhaustion. Consider adding authentication checks or rate limiting.

Copilot uses AI. Check for mistakes.
}

try {
const { files, projectName = 'x-builder-preview' } = await request.json<PublishRequest>();
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The projectName parameter lacks validation. Malicious values could potentially be used in path traversal or injection attacks when used in the API URL. Consider validating that it matches Cloudflare's project naming requirements (alphanumeric and hyphens only, specific length limits).

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +40
if (!files || Object.keys(files).length === 0) {
return json({ error: 'No files provided for publishing' }, { status: 400 });
}
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

There's no validation on file sizes or total payload size. A user could upload extremely large files, potentially causing memory issues or exceeding Cloudflare's size limits. Consider adding reasonable size limits and validation.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +13
# Only deploy after CI passes
needs: []
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The comment states "Only deploy after CI passes" but the needs array is empty. If there's a CI job that should run before deployment, it should be referenced here (e.g., needs: [ci]). Otherwise, deployments will run without waiting for CI validation.

Suggested change
# Only deploy after CI passes
needs: []

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +21
"preview": "pnpm run build && pnpm run start",
"smoke:publish": "tsx scripts/smoke-test-publish.ts"
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The script 'smoke:publish' references 'scripts/smoke-test-publish.ts' but this file does not exist in the repository. This script will fail when executed.

Suggested change
"preview": "pnpm run build && pnpm run start",
"smoke:publish": "tsx scripts/smoke-test-publish.ts"
"preview": "pnpm run build && pnpm run start"

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +79
for (const [filePath, content] of Object.entries(files)) {
// normalize path to include leading slash (required by CF Pages)
const normalizedPath = filePath.startsWith('/') ? filePath : `/${filePath}`;
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

File paths from the request are not validated for malicious content. A user could potentially include paths like '../../../etc/passwd' or other path traversal attempts. Consider validating that paths don't contain '..' segments and are within expected boundaries.

Copilot uses AI. Check for mistakes.
const response = await handler(context);

// clone response to modify headers
const newResponse = new Response(response.body, response);
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

Creating a new Response with response.body may fail if the response body has already been consumed or is not readable. Consider using response.clone() before creating the new response to avoid potential stream consumption issues.

Suggested change
const newResponse = new Response(response.body, response);
const newResponse = response.clone();

Copilot uses AI. Check for mistakes.
/**
* Wrap handler to add COOP/COEP headers for crossOriginIsolated.
*/
export const onRequest: PagesFunction = async (context) => {
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The type PagesFunction is used but not imported. This will cause a TypeScript error. Import it from '@cloudflare/workers-types' or use the appropriate type definition.

Copilot uses AI. Check for mistakes.
// project might already exist (409), which is fine
if (!projectResponse.ok && projectResponse.status !== 409) {
const errorData = await projectResponse.json();
console.error('Failed to create project:', errorData);
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

When the project creation fails (non-409 status), the error is logged but execution continues. This could lead to deployment attempts on non-existent projects. Consider returning an error response or at least validating the project exists before attempting deployment.

Suggested change
console.error('Failed to create project:', errorData);
console.error('Failed to create project:', errorData);
return json(
{
error: 'Failed to create project before deployment.',
details: errorData,
},
{ status: projectResponse.status || 502 },
);

Copilot uses AI. Check for mistakes.
deploymentId: deployResult.result?.id,
});
} catch (error) {
console.error('Publish error:', error);
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The generic catch block doesn't differentiate between JSON parsing errors from request.json() and other errors. If the request body is malformed JSON, a more specific error message would be helpful (e.g., 'Invalid request body').

Suggested change
console.error('Publish error:', error);
console.error('Publish error:', error);
if (error instanceof SyntaxError) {
// Likely caused by malformed JSON in the request body
return json({ error: 'Invalid request body' }, { status: 400 });
}

Copilot uses AI. Check for mistakes.
@yosiwizman yosiwizman closed this Jan 6, 2026
@yosiwizman yosiwizman deleted the fix/publish-api-manifest branch January 6, 2026 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant