Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
},
"metadata": {
"description": "Agentuity plugins for Claude Code",
"version": "3.1.16"
"version": "3.1.17"
},
"plugins": [
{
"name": "agentuity",
"source": "./packages/claude-code",
"description": "Deploy websites, apps, and AI agents to Agentuity — with managed databases, storage, queues, and more",
"version": "3.1.16",
"version": "3.1.17",
"author": {
"name": "Agentuity"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sdk-mono",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"packageManager": "bun@1.3.11",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/adapter",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity employees and contributors",
"description": "HTTP client adapter for Agentuity service clients",
Expand Down
2 changes: 1 addition & 1 deletion packages/aigateway/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/aigateway",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity employees and contributors",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion packages/analytics/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/analytics",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity employees and contributors",
"description": "Browser analytics for Agentuity applications",
Expand Down
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/api",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity employees and contributors",
"description": "Platform HTTP client for Agentuity control-plane APIs",
Expand Down
2 changes: 1 addition & 1 deletion packages/claude-code/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agentuity",
"version": "3.1.16",
"version": "3.1.17",
"description": "Deploy websites, apps, and AI agents to Agentuity — with managed databases, storage, queues, and more",
"author": {
"name": "Agentuity",
Expand Down
2 changes: 1 addition & 1 deletion packages/claude-code/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/claude-code",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity",
"description": "Claude Code plugin for deploying websites, apps, and AI agents to Agentuity — with managed databases, storage, sandboxes, queues, cron, email, and more",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/cli",
"version": "3.1.16",
"version": "3.1.17",
"license": "Apache-2.0",
"author": "Agentuity employees and contributors",
"type": "module",
Expand Down
8 changes: 8 additions & 0 deletions packages/cli/src/cmd/build/adapters/nextjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,15 @@ export const nextjsAdapter: BuildAdapter = {
}

// Copy `public/` next to server.js for the same reason.
// Next assetPrefix only rewrites /_next/* — public/ files
// (e.g. /next.svg) stay origin-relative. Packaging owns CDN
// rewrite + launch.static.include when publicStaticDir is set.
let packagedPublicDir: string | undefined;
if (existsSync(publicPath)) {
const publicDst = join(serverDir, 'public');
mkdirSync(publicDst, { recursive: true });
cpSync(publicPath, publicDst, { recursive: true });
packagedPublicDir = publicDst;
}

logs.push(
Expand All @@ -257,6 +262,7 @@ export const nextjsAdapter: BuildAdapter = {
workingDirectory,
staticDir: packagedStaticDir,
staticAssetPublicPath: framework.staticAssetPublicPath,
publicStaticDir: packagedPublicDir,
port: framework.port ?? 3000,
duration: Date.now() - started,
logs,
Expand All @@ -267,6 +273,8 @@ export const nextjsAdapter: BuildAdapter = {
// and the package manifests Hadron needs to install production
// dependencies before launch. This path is brittle (`next start`
// needs the full Next.js install) so we warn the user.
// Public CDN rewrite / launch.static.include require standalone
// packaging (publicStaticDir is only set on that path).
logger.debug('No standalone output found — copying full .next directory');
const nextDst = join(outputDir, '.next');
cpSync(join(projectDir, '.next'), nextDst, { recursive: true });
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/src/cmd/build/adapters/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export interface BuildResult {
/** Public URL path prefix for files inside staticDir */
staticAssetPublicPath?: string;

/**
* Absolute path to packaged root-public assets (e.g. Next `public/`).
* Used when {@link staticAssetPublicPath} is a non-empty built prefix
* (`_next/static`) so CDN upload + HTML rewrite can also ship `/logo.svg`.
*/
publicStaticDir?: string;

/** Port the app listens on */
port?: number;

Expand Down
62 changes: 58 additions & 4 deletions packages/cli/src/cmd/build/package/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@
* Build output packaging.
*
* After a framework adapter builds the project, the packager:
* 1. Generates launch metadata (how to start the app)
* 2. Writes launch.json
* 1. Rewrites root-public asset URLs onto the CDN base when applicable
* 2. Generates launch metadata (how to start the app)
* 3. Writes launch.json
*
* The output is a self-contained directory ready for deployment
* as a buildpack image layer or traditional zip upload.
*
* Public CDN policy lives here (not in framework adapters): adapters only
* stage files and set `BuildResult.publicStaticDir`; packaging owns
* rewrite + `launch.static.include`.
*/

import type { DetectedFramework } from '../detect/types.ts';
import type { MonorepoContext } from '../detect/monorepo.ts';
import type { BuildResult } from '../adapters/types.ts';
import { resolveAgentuityCdnBase } from '../adapters/cdn-origin.ts';
import {
generateLaunchMetadata,
isSplitCdnLayout,
readUserLaunchOverride,
resolveProcessRoot,
writeLaunchMetadata,
type LaunchMetadata,
} from './launch.ts';
import { rewritePublicAssetUrlsInTree } from './public-cdn.ts';

export interface PackageResult {
/** Absolute path to the packaged output */
Expand All @@ -31,13 +40,42 @@ export interface PackageResult {

/** Path to static assets (if any) */
staticDir?: string;

/** Human-readable packaging log lines (e.g. public URL rewrites) */
logs: string[];
}

export interface PackageBuildOutputOptions {
/** Explicit CDN base URL from `--cdn-base-url` (written to launch.static.baseUrl). */
cdnBaseUrl?: string;
}

/**
* When CDN base is known and packaging staged a split-layout public root,
* rewrite root-absolute `/file` refs under the process tree to the CDN base.
*/
function rewriteStagedPublicAssets(
buildResult: BuildResult,
monorepo: MonorepoContext | undefined,
cdnBase: string
): string[] {
const logs: string[] = [];
if (!buildResult.publicStaticDir) return logs;

const publicPath = buildResult.staticAssetPublicPath ?? '';
if (!isSplitCdnLayout(publicPath)) return logs;

const treeRoot = resolveProcessRoot(buildResult, monorepo);
const rw = rewritePublicAssetUrlsInTree(treeRoot, buildResult.publicStaticDir, cdnBase);
if (rw.publicFileCount > 0) {
logs.push(
`✓ CDN: rewrote public/ refs in ${rw.filesChanged}/${rw.filesScanned} files ` +
`(${rw.publicFileCount} public asset(s) → ${cdnBase})`
);
}
return logs;
}

/**
* Package a build result into a deployment-ready directory.
*
Expand All @@ -54,6 +92,14 @@ export async function packageBuildOutput(
options?: PackageBuildOutputOptions
): Promise<PackageResult> {
const override = projectDir ? await readUserLaunchOverride(projectDir) : null;
const logs: string[] = [];

// Same CDN chain as launch.static.baseUrl / adapters. Rewrite before
// writing launch.json so staged HTML/JS already point at the CDN.
const cdnBase = resolveAgentuityCdnBase({ cdnBaseUrl: options?.cdnBaseUrl });
if (cdnBase) {
logs.push(...rewriteStagedPublicAssets(buildResult, monorepo, cdnBase));
}

// Generate launch metadata (with optional user override applied).
// In monorepo mode, every process inherits the subpackage as its
Expand All @@ -74,8 +120,16 @@ export async function packageBuildOutput(
launch,
hasStaticAssets: !!buildResult.staticDir || !!launch.static,
staticDir: buildResult.staticDir,
logs,
};
}

// Re-export
export type { LaunchMetadata, LaunchStaticAssets, ProcessDefinition } from './launch.ts';
// Re-export public launch contract types (not rewrite helpers — those stay
// package-internal / testable via their module path).
export type {
LaunchMetadata,
LaunchStaticAssets,
LaunchStaticRoot,
ProcessDefinition,
} from './launch.ts';
export { joinCdnAssetUrl } from './launch.ts';
Loading
Loading