Skip to content
Open
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
17 changes: 17 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
[build]
rustflags = ["--cfg", "tokio_unstable"]

# Target-specific flags must repeat tokio_unstable because target rustflags
# override [build] rustflags. The link args are required on macOS for native
# Node.js addons (dynamic_lookup defers symbol resolution to runtime).
[target.aarch64-apple-darwin]
rustflags = [
"--cfg", "tokio_unstable",
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

[target.x86_64-apple-darwin]
rustflags = [
"--cfg", "tokio_unstable",
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

[env]
LIBSQLITE3_FLAGS = "SQLITE_ENABLE_BATCH_ATOMIC_WRITE"
10 changes: 0 additions & 10 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -461,16 +461,6 @@ jobs:
--version ${{ needs.context.outputs.version }} \
--latest ${{ needs.context.outputs.latest }}

- name: Upload @rivetkit/devtools to R2
if: needs.context.outputs.trigger == 'release'
env:
R2_RELEASES_ACCESS_KEY_ID: ${{ secrets.R2_RELEASES_ACCESS_KEY_ID }}
R2_RELEASES_SECRET_ACCESS_KEY: ${{ secrets.R2_RELEASES_SECRET_ACCESS_KEY }}
run: |
pnpm --filter=publish exec tsx src/ci/bin.ts upload-devtools \
--sha ${{ needs.context.outputs.sha }} \
--version ${{ needs.context.outputs.version }} \
--latest ${{ needs.context.outputs.latest }}

- name: Retag Docker manifests to version
if: needs.context.outputs.trigger == 'release'
Expand Down
2 changes: 1 addition & 1 deletion rivetkit-typescript/packages/devtools/src/mod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ const openDevtools = () => {
console.error("RivetKit Devtools: No client config found");
return;
}
const url = new URL("http://localhost:6420/ui");
if (!config.endpoint) {
console.error("RivetKit Devtools: No endpoint found in client config");
return;
}
const url = new URL(`${config.endpoint.replace(/\/$/, "")}/ui`);
url.searchParams.set("u", config.endpoint);
if (config.token) {
url.searchParams.set("t", config.token);
Expand Down
3 changes: 2 additions & 1 deletion rivetkit-typescript/packages/rivetkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@
"dump-asyncapi": "tsx scripts/dump-asyncapi.ts",
"registry-config-schema-gen": "tsx scripts/registry-config-schema-gen.ts",
"actor-config-schema-gen": "tsx scripts/actor-config-schema-gen.ts",
"build:pack-inspector": "tsx scripts/pack-inspector.ts"
"build:pack-inspector": "tsx scripts/pack-inspector.ts",
"build:pack-devtools": "tsx scripts/pack-devtools.ts"
},
"dependencies": {
"@rivet-dev/agent-os-core": "^0.1.1",
Expand Down
19 changes: 19 additions & 0 deletions rivetkit-typescript/packages/rivetkit/scripts/pack-devtools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { existsSync } from "node:fs";
import { copyFile, mkdir } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const src = join(__dirname, "../../devtools/dist/mod.js");
const destDir = join(__dirname, "../dist/devtools");
const dest = join(destDir, "mod.js");

if (!existsSync(src)) {
throw new Error(
`Devtools build not found at: ${src}. Run 'pnpm build -F @rivetkit/devtools' first.`,
);
}

await mkdir(destDir, { recursive: true });
await copyFile(src, dest);
console.log(`Packed devtools into ${dest}`);
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import type { ClientConfigInput } from "@/client/client";
import { VERSION } from "@/utils";
import { logger } from "./log";

declare global {
// Injected via tsup config
// biome-ignore lint/style/noVar: required for global declaration
var CUSTOM_RIVETKIT_DEVTOOLS_URL: string | undefined;
}

const DEFAULT_DEVTOOLS_URL = (version = VERSION) =>
`https://releases.rivet.dev/rivet/latest/devtools/mod.js?v=${version}`;

const scriptId = "rivetkit-devtools-script";

export function injectDevtools(config: ClientConfigInput) {
Expand All @@ -20,10 +15,12 @@ export function injectDevtools(config: ClientConfigInput) {
}

if (!document.getElementById(scriptId)) {
const src =
globalThis.CUSTOM_RIVETKIT_DEVTOOLS_URL ||
`${config.endpoint?.replace(/\/$/, "")}/devtools/mod.js`;
const script = document.createElement("script");
script.id = scriptId;
script.src =
globalThis.CUSTOM_RIVETKIT_DEVTOOLS_URL || DEFAULT_DEVTOOLS_URL();
script.src = src;
script.async = true;
document.head.appendChild(script);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { getNodeFs, getNodePath, getNodeUrl } from "@/utils/node";

export async function getDevtoolsPath(): Promise<string> {
const url = getNodeUrl();
const path = getNodePath();

const devtoolsPath = path.join(
path.dirname(url.fileURLToPath(import.meta.url)),
"../../dist/devtools/mod.js",
);

try {
await getNodeFs().access(devtoolsPath);
} catch {
throw new Error(
`Devtools bundle not found at ${devtoolsPath}. Run 'pnpm build:pack-devtools' first.`,
);
}

return devtoolsPath;
}

export async function readDevtoolsBundle(): Promise<Buffer> {
const devtoolsPath = await getDevtoolsPath();
return getNodeFs().readFile(devtoolsPath);
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ export class EngineActorDriver implements ActorDriver {
token: config.token,
namespace: config.namespace,
poolName: config.envoy.poolName,
notGlobal: false,
metadata: {
rivetkit: { version: VERSION },
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class EngineApiError extends Error {
export function getEndpoint(config: ClientConfig | RegistryConfig) {
// Endpoint is always defined for ClientConfig (has default in schema).
// RegistryConfig may not have endpoint before the local runtime is prepared.
return config.endpoint ?? "http://127.0.0.1:6420";
return config.endpoint ?? "http://127.0.0.1:6423";
}

// Helper function for making API calls
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export const ENGINE_PORT = 6420;
// The engine guard (public HTTP API) runs on this internal port.
// The rivetkit manager runs on port 6420 (managerPort default) and proxies to
// the engine here, so clients always connect to the manager on 6420.
export const ENGINE_PORT = 6423;
export const ENGINE_ENDPOINT = `http://127.0.0.1:${ENGINE_PORT}`;
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function ensureEngineProcess(
error,
});
throw new Error(
"Engine process exists but is not healthy. Please manually stop the process on port 6420 and retry.",
`Engine process exists but is not healthy. Please manually stop the process on port ${ENGINE_PORT} and retry.`,
);
}
}
Expand Down Expand Up @@ -129,6 +129,9 @@ export async function ensureEngineProcess(
//
// We reduce the timeouts for resetting a runner as healthy in
// order to account for this.
// Run the engine guard on its internal port so the rivetkit manager
// can own the default client port (6420) and serve devtools/inspector.
RIVET__GUARD__PORT: String(ENGINE_PORT),
RIVET__PEGBOARD__RETRY_RESET_DURATION: "100",
RIVET__PEGBOARD__BASE_RETRY_TIMEOUT: "100",
// Set max exponent to 1 to have a maximum of base_retry_timeout
Expand Down Expand Up @@ -305,11 +308,11 @@ async function checkIfEngineAlreadyRunningOnPort(
port,
});
throw new Error(
"RivetKit process already running on port 6420, stop that process and restart this.",
`RivetKit process already running on port ${port}, stop that process and restart this.`,
);
} else {
throw new Error(
"Unknown process running on port 6420, cannot identify what it is.",
`Unknown process running on port ${port}, cannot identify what it is.`,
);
}
}
Expand Down
30 changes: 21 additions & 9 deletions rivetkit-typescript/packages/rivetkit/src/runtime-router/router.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import { createRoute } from "@hono/zod-openapi";
import * as cbor from "cbor-x";
import type { Hono } from "hono";
import invariant from "invariant";
import { z } from "zod/v4";
import { Forbidden, RestrictedFeature } from "@/actor/errors";
import { deserializeActorKey, serializeActorKey } from "@/actor/keys";
import {
actorGateway,
createTestWebSocketProxy,
} from "@/actor-gateway/gateway";
import type { Encoding } from "@/client/mod";
import {
HEADER_RIVET_TOKEN,
WS_PROTOCOL_ACTOR,
WS_PROTOCOL_CONN_PARAMS,
WS_PROTOCOL_ENCODING,
WS_TEST_PROTOCOL_PATH,
} from "@/common/actor-router-consts";
import { handleHealthRequest, handleMetadataRequest } from "@/common/router";
import { deconstructError, noopNext, stringifyError } from "@/common/utils";
import { stringifyError } from "@/common/utils";

import { HEADER_ACTOR_ID } from "@/driver-helpers/mod";
import {
ActorsCreateRequestSchema,
type ActorsCreateResponse,
Expand Down Expand Up @@ -469,6 +461,26 @@ export function buildRuntimeRouter(
router.get("/ui", (c) => c.redirect("/ui/"));
}

router.get("/devtools/mod.js", async (c) => {
let content: Buffer;
try {
content = await readDevtoolsBundle();
} catch (error) {
logger().error({
msg: "devtools bundle not found",
error: stringifyError(error),
});
return c.text("Devtools bundle not found.", 404);
}

return new Response(new Uint8Array(content), {
headers: {
"Content-Type": "application/javascript",
"Access-Control-Allow-Origin": "*",
},
});
});

router.get("/health", (c) => handleHealthRequest(c));

router.get("/metadata", (c) =>
Expand Down
7 changes: 6 additions & 1 deletion rivetkit-typescript/packages/rivetkit/turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
"inputs": ["scripts/pack-inspector.ts", "package.json"],
"outputs": ["dist/inspector.tar.gz"]
},
"build:pack-devtools": {
"dependsOn": ["@rivetkit/devtools#build"],
"inputs": ["scripts/pack-devtools.ts", "package.json"],
"outputs": ["dist/devtools/mod.js"]
},
"build:dynamic-isolate-runtime": {
"dependsOn": ["^build", "build:schema"],
"inputs": [
Expand Down Expand Up @@ -98,7 +103,7 @@
]
},
"build:publish": {
"dependsOn": ["build", "build:pack-inspector"],
"dependsOn": ["build", "build:pack-inspector", "build:pack-devtools"],
"outputs": []
}
}
Expand Down
Loading