Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b5fbccb
wip
ef4 Dec 10, 2025
47978de
Merge remote-tracking branch 'origin/main' into vite
ef4 Dec 18, 2025
346cde8
patching postcss
ef4 Dec 18, 2025
0897928
shim some environment stuff
ef4 Dec 18, 2025
80e18a2
Merge branch 'main' into vite
ef4 Jan 8, 2026
465937a
Fix transitive dep skipping
ef4 Jan 8, 2026
2593265
Merge branch 'fix-skip-dep-resolution' into vite
ef4 Jan 8, 2026
27ecdb6
updating some embroider config for the new major
ef4 Jan 14, 2026
873b405
we only need to eagerly load actual tests
ef4 Jan 14, 2026
0c4fed6
guard undici, etc
ef4 Jan 14, 2026
3d3962a
progress
ef4 Jan 14, 2026
761f3cf
Merge branch 'main' into vite
ef4 Feb 5, 2026
883438d
patching incompatible behavior in dep
ef4 Feb 5, 2026
868f059
this is a type-only import
ef4 Feb 5, 2026
b64929c
dropping ember-monaco-polyfill
ef4 Feb 5, 2026
44ad567
wip
ef4 Feb 12, 2026
a9c1412
setting up monaco workers
ef4 Feb 18, 2026
1d18fcf
scoped css in host app
ef4 Feb 18, 2026
2e62512
ETAG cache invalidatoin
ef4 Feb 18, 2026
b38d5df
Merge remote-tracking branch 'origin/main' into vite
ef4 Feb 18, 2026
747421e
keeping our version of index.html, post-merge
ef4 Feb 18, 2026
c895ed6
making lints bpass
ef4 Feb 19, 2026
e554402
type updates
ef4 Feb 19, 2026
223a8dd
Merge remote-tracking branch 'origin/main' into vite
ef4 Feb 25, 2026
ce43527
don't ship jsonwebtoken to the browser
ef4 Feb 25, 2026
5b4af70
lint fix
ef4 Feb 25, 2026
9cd7b02
reconfiguring tests/index.html ci handling
ef4 Feb 25, 2026
76d47e2
change strategy to prevent rollup from stripping this eval-visible local
ef4 Feb 25, 2026
7e81686
another deprecation for workflow
ef4 Feb 25, 2026
e4eca3e
updating ember private api for 6.10
ef4 Feb 26, 2026
b895c32
clean up content tag global
ef4 Feb 26, 2026
3ab1375
keep old monaco global for tests
ef4 Feb 26, 2026
d31a956
Merge remote-tracking branch 'origin/main' into vite
ef4 Mar 4, 2026
276348b
Merge branch 'main' into vite
ef4 Apr 2, 2026
18da70d
post-merge cleanup
ef4 Apr 2, 2026
d12e717
ember-exam WIP
ef4 Apr 3, 2026
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: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@
"@embroider/compat": "patches/@embroider__compat.patch",
"ember-eslint-parser": "patches/ember-eslint-parser.patch",
"openai": "patches/openai.patch",
"postcss@8.5.6": "patches/postcss@8.5.6.patch",
"matrix-js-sdk@38.3.0": "patches/matrix-js-sdk@38.3.0.patch",
"@embroider/webpack": "patches/@embroider__webpack.patch",
"ember-source": "patches/ember-source.patch"
"ember-source": "patches/ember-source.patch",
"object-inspect": "patches/object-inspect.patch"
},
"onlyBuiltDependencies": [
"@percy/core",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'ember-power-calendar/styles';
import 'ember-power-calendar/styles';

import { fn } from '@ember/helper';
import { on } from '@ember/modifier';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'ember-power-select/styles';
import 'ember-power-select/styles';

import Component from '@glimmer/component';
import type { ComponentLike } from '@glint/template';
Expand Down
1 change: 1 addition & 0 deletions packages/boxel-ui/addon/src/components/select/index.gts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'ember-power-select/styles';
import 'ember-power-select/styles';

import Check from '@cardstack/boxel-icons/check';
import { eq } from '@cardstack/boxel-ui/helpers';
Expand Down
1 change: 1 addition & 0 deletions packages/host/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ module.exports = {
'./config/**/*.js',
'./lib/**/*.js',
'./server/**/*.js',
'./babel.config.cjs',
'./scripts/**/*.js',
],
parserOptions: {
Expand Down
2 changes: 2 additions & 0 deletions packages/host/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/tmp/

# compiled output
/dist/
/declarations/
Expand Down
9 changes: 5 additions & 4 deletions packages/host/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import './deprecation-workflow';
import Application from '@ember/application';
import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from '@cardstack/host/config/environment';
import './lib/glint-embroider-workaround';
import config from './config/environment';
import '@cardstack/boxel-ui/styles/global.css';
import '@cardstack/boxel-ui/styles/fonts.css';
import '@cardstack/boxel-ui/styles/variables.css';

import compatModules from '@embroider/virtual/compat-modules';

export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
Resolver = Resolver.withModules(compatModules);
}

loadInitializers(App, config.modulePrefix);
loadInitializers(App, config.modulePrefix, compatModules);
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
export default config;
import { assert } from '@ember/debug';
import loadConfigFromMeta from '@embroider/config-meta-loader';

/**
* Type declarations for
* import config from 'my-app/config/environment'
*/
declare const config: {
const config = loadConfigFromMeta('@cardstack/host') as unknown;

assert(
'config is not an object',
typeof config === 'object' && config !== null,
);
assert(
'modulePrefix was not detected on your config',
'modulePrefix' in config && typeof config.modulePrefix === 'string',
);
assert(
'locationType was not detected on your config',
'locationType' in config && typeof config.locationType === 'string',
);
assert(
'rootURL was not detected on your config',
'rootURL' in config && typeof config.rootURL === 'string',
);
assert(
'APP was not detected on your config',
'APP' in config && typeof config.APP === 'object',
);

export default config as {
environment: string;
modulePrefix: string;
podModulePrefix: string;
Expand Down Expand Up @@ -38,10 +58,12 @@ declare const config: {
SHOW_ASK_AI?: boolean;
AI_PATCHING_CORRECTNESS_CHECKS?: boolean;
};
publishedRealmDomainOverrides: string;
publishedRealmBoxelSpaceDomain: string;
publishedRealmBoxelSiteDomain: string;
publishedRealmDomainOverrides: string;
defaultSystemCardId?: string;
cardSizeLimitBytes: number;
fileSizeLimitBytes: number;
};
defaultSystemCardId: string;
} & Record<string, unknown>;
12 changes: 0 additions & 12 deletions packages/host/app/lib/glint-embroider-workaround.js

This file was deleted.

6 changes: 0 additions & 6 deletions packages/host/app/lib/public-path.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
import config from '@cardstack/host/config/environment';

(globalThis as any).__bootStart = performance.now();
const { hostsOwnAssets, assetsURL } = config;

// @ts-expect-error this is consumed by webpack to set the public asset path at runtime
__webpack_public_path__ = hostsOwnAssets ? '/' : assetsURL;
1 change: 0 additions & 1 deletion packages/host/app/modifiers/monaco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import * as MonacoSDK from 'monaco-editor';
import config from '@cardstack/host/config/environment';
import type MonacoService from '@cardstack/host/services/monaco-service';
import { createMonacoWaiterManager } from '@cardstack/host/utils/editor/monaco-test-waiter';
import '@cardstack/requirejs-monaco-ember-polyfill';

interface Signature {
Args: {
Expand Down
40 changes: 38 additions & 2 deletions packages/host/app/services/monaco-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import { task } from 'ember-concurrency';

import merge from 'lodash/merge';

// The worker suffix here is a vite feature that builds them into standalone
// worker scripts, which will be outside the main bundle in prod.
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js?worker';
import CSSWorker from 'monaco-editor/esm/vs/language/css/css.worker.js?worker';
import HTMLWorker from 'monaco-editor/esm/vs/language/html/html.worker.js?worker';
import JSONWorker from 'monaco-editor/esm/vs/language/json/json.worker.js?worker';
import TSWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker.js?worker';

import type { SingleCardDocument } from '@cardstack/runtime-common';

import config from '@cardstack/host/config/environment';
Expand All @@ -28,6 +36,28 @@ export type MonacoSDK = typeof _MonacoSDK;
export type IStandaloneCodeEditor = _MonacoSDK.editor.IStandaloneCodeEditor;

const { serverEchoDebounceMs } = config;
(
globalThis as unknown as { MonacoEnvironment: _MonacoSDK.Environment }
).MonacoEnvironment = {
getWorker: function (_workerId, label) {
switch (label) {
case 'json':
return new JSONWorker();
case 'css':
case 'scss':
case 'less':
return new CSSWorker();
case 'typescript':
case 'javascript':
return new TSWorker();
case 'html':
case 'handlebars':
return new HTMLWorker();
default:
return new EditorWorker();
}
},
};

export default class MonacoService extends Service {
#ready: Promise<MonacoSDK>;
Expand Down Expand Up @@ -60,9 +90,15 @@ export default class MonacoService extends Service {
}

private loadMonacoSDK = task(async () => {
// @ts-expect-error: dynamic import without types
await import('@cardstack/requirejs-monaco-ember-polyfill');
const monaco = await import('monaco-editor');

// There are tests that rely on this. In older Ember versions, Monaco
// installed itself as a global automatically because it does that when it
// detects the presence of an AMD in the environment. Newer Ember versions
// (with Vite) don't use AMD anymore, so Monaco stopped putting itself on
// this global.
(globalThis as any).monaco = monaco;

monaco.languages.typescript.javascriptDefaults.setCompilerOptions(
this.defaultCompilerOptions(monaco),
);
Expand Down
53 changes: 53 additions & 0 deletions packages/host/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const {
babelCompatSupport,
templateCompatSupport,
} = require('@embroider/compat/babel');

module.exports = {
plugins: [
[
'@babel/plugin-transform-typescript',
{
allExtensions: true,
onlyRemoveTypeImports: true,
allowDeclareFields: true,
},
],
[
'babel-plugin-ember-template-compilation',
{
compilerPath: 'ember-source/dist/ember-template-compiler.js',
enableLegacyModules: [
'ember-cli-htmlbars',
'ember-cli-htmlbars-inline-precompile',
'htmlbars-inline-precompile',
],
transforms: [
...templateCompatSupport(),
'glimmer-scoped-css/ast-transform',
],
},
],
[
'module:decorator-transforms',
{
runtime: {
import: require.resolve('decorator-transforms/runtime-esm'),
},
},
],
[
'@babel/plugin-transform-runtime',
{
absoluteRuntime: __dirname,
useESModules: true,
regenerator: false,
},
],
...babelCompatSupport(),
],

generatorOpts: {
compact: false,
},
};
1 change: 0 additions & 1 deletion packages/host/config/targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ const browsers = [

module.exports = {
browsers,
node: 'current',
};
101 changes: 5 additions & 96 deletions packages/host/ember-cli-build.js
Original file line number Diff line number Diff line change
@@ -1,114 +1,23 @@
'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const { compatBuild } = require('@embroider/compat');
const { Webpack } = require('@embroider/webpack');
const webpack = require('webpack');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const { GlimmerScopedCSSWebpackPlugin } = require('glimmer-scoped-css/webpack');
const withSideWatch = require('./lib/with-side-watch');
const Funnel = require('broccoli-funnel');
const { BoxelUIChecksumPlugin } = require('./lib/build/package-dist-checksums');

module.exports = function (defaults) {
module.exports = async function (defaults) {
const { buildOnce } = await import('@embroider/vite');

const app = new EmberApp(defaults, {
trees: {
app: withSideWatch('app', {
watching: ['../runtime-common', '../boxel-ui/addon'],
}),
},
'ember-cli-babel': {
enableTypeScriptTransform: true,
disableDecoratorTransforms: true,
},
babel: {
plugins: [
[require.resolve('decorator-transforms')],
require.resolve('ember-concurrency/async-arrow-task-transform'),
],
},
});

return compatBuild(app, Webpack, {
staticAddonTrees: true,
staticAddonTestSupportTrees: true,
staticHelpers: true,

staticComponents: true,

staticModifiers: true,
return compatBuild(app, buildOnce, {
staticInvokables: true,
staticAppPaths: ['lib'],
extraPublicTrees: [
new Funnel('node_modules/content-tag/pkg', {
include: ['standalone.js', 'standalone/*'],
destDir: 'assets/content-tag',
}),
],
packagerOptions: {
...{
webpackConfig: {
devtool: 'source-map',
module: {
rules: [
{
test: /\.ttf$/,
type: 'asset/inline',
},
{
test: /\.woff2$/,
type: 'asset',
},
{
test: /\.png$/,
type: 'asset',
},
{
test: /\.webp$/,
type: 'asset',
},
{
test: /\.otf$/,
type: 'asset',
},
],
},
plugins: [
new GlimmerScopedCSSWebpackPlugin(),
new MonacoWebpackPlugin(),
new webpack.IgnorePlugin({
resourceRegExp: /^https:\/\/cardstack\.com\/base/,
}),
new MomentLocalesPlugin({
// 'en' is built into moment and cannot be removed. This strips the others.
localesToKeep: [],
}),
// boxel-ui packages dist checksum needed for the realm server to figure out if boxel-ui changed, and trigger a reindex of cards that use it (to update cards' prerendered HTML)
new BoxelUIChecksumPlugin(__dirname),
],
externals: {
'content-tag': 'ContentTagGlobal',
},
resolve: {
fallback: {
fs: false,
os: false,
path: require.resolve('path-browserify'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
assert: require.resolve('assert/'),
},
alias: {
// Exclude the rust-crypto module from the bundle because we don't use it
'matrix-js-sdk$': 'matrix-js-sdk/src/browser-index.ts',
'./rust-crypto/index.ts': false,
},
},
node: {
global: true,
},
},
},
},
});
};
Loading