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
1 change: 1 addition & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"!**/pnpm-lock.yaml",
"!**/swagger-spec.json",
"!playground",
"!packages/novu/src/commands/connect/templates/web-chat",
"!libs/internal-sdk",
"!.github",
"!scripts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

The CLI already wrote the Novu environment values.

Add a minimal Web Chat UI with `@novu/react` (`NovuProvider` and `useWebChat`). After the UI change, the first line of your final user-facing message must be:
Add a Web Chat UI with `@novu/react` (`NovuProvider` and `useWebChat`) and assistant-ui unless the app already has another chat library. After the UI change, the first line of your final user-facing message must be:

✓ Web Chat connected
14 changes: 13 additions & 1 deletion packages/novu/scripts/build-ui.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ const sharedConfig = {
jsxImportSource: 'react',
sourcemap: false,
logLevel: 'info',
// Keep @inkjs/ui in the bundle. It has no `react` peer, so a runtime
// import from this monorepo resolves repo-root React 18 while Ink 7
// renders React 19. Select/TextInput then crash on useReducer.
external: [
'react',
'react/jsx-runtime',
'ink',
'ink-scroll-view',
'@inkjs/ui',
'ink-spinner',
'chalk',
'marked',
Expand Down Expand Up @@ -58,6 +60,16 @@ await build({
outfile: resolve(root, 'dist/src/commands/connect/ui/index.mjs'),
});

for (const outfile of [
resolve(root, 'dist/src/commands/wizard/ui/index.mjs'),
resolve(root, 'dist/src/commands/connect/ui/index.mjs'),
]) {
const source = readFileSync(outfile, 'utf8');
if (source.includes('from "@inkjs/ui"') || source.includes("from '@inkjs/ui'")) {
throw new Error(`${outfile} still imports @inkjs/ui. It must stay bundled so Select uses the CLI React.`);
}
}

/**
* Bundle the CLI entry, replacing the tsc-emitted dist/src/index.js.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'node:path';
import { installPackages } from '../../../init/helpers/install';
import { formatNpmInstallCommand, installPackages } from '../../../init/helpers/install';
import { detectPackageManager } from '../../../step/utils/package-manager';
import { getDependencyVersion, hasDependency, readProjectPackageJson } from '../bridge/project-package';

Expand Down Expand Up @@ -49,7 +49,7 @@ function buildInstallCommand(projectDir: string, packages: string[]): string {
case 'bun':
return `bun add ${packageList}`;
default:
return `npm install ${packageList} --no-workspaces`;
return formatNpmInstallCommand(packages);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ describe('resolveChatSdkPackagesToInstall', () => {
);

expect(resolveChatSdkPackagesToInstall(dir)).toEqual(['@novu/chat-sdk-adapter']);
expect(buildChatSdkInstallCommand(dir)).toBe('npm install @novu/chat-sdk-adapter --no-workspaces');
expect(buildChatSdkInstallCommand(dir)).toBe(
'npm install @novu/chat-sdk-adapter --no-workspaces --no-audit --fund=false'
);
});

it('includes state-memory only when no state adapter is present', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'node:path';
import { installPackages } from '../../../init/helpers/install';
import { formatNpmInstallCommand, installPackages } from '../../../init/helpers/install';
import { detectPackageManager } from '../../../step/utils/package-manager';
import { hasDependency, readProjectPackageJson } from '../bridge/project-package';

Expand Down Expand Up @@ -69,7 +69,7 @@ export function buildChatSdkInstallCommand(projectDir: string): string {
case 'bun':
return `bun add ${packageList}`;
default:
return `npm install ${packageList} --no-workspaces`;
return formatNpmInstallCommand(packages);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'node:path';
import { installPackages } from '../../../init/helpers/install';
import { formatNpmInstallCommand, installPackages } from '../../../init/helpers/install';
import { detectPackageManager } from '../../../step/utils/package-manager';
import { hasDependency, readProjectPackageJson } from '../bridge/project-package';

Expand Down Expand Up @@ -34,7 +34,7 @@ function buildInstallCommand(projectDir: string, packages: string[]): string {
case 'bun':
return `bun add ${packageList}`;
default:
return `npm install ${packageList} --no-workspaces`;
return formatNpmInstallCommand(packages);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { NOVU_STAGING_API_URL } from '@novu/shared';
import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import { CloudRegionEnum } from '../../../dev/enums';

vi.mock('../../../init/helpers/is-online', () => ({
getOnline: vi.fn(async () => false),
}));

import {
assertSafeScaffoldDirectoryName,
resolveWebChatNovuDependencies,
Expand Down
Loading
Loading