assistant-ui 0.0.115 → 0.0.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codemods/utils/createTransformer.d.ts +3 -4
- package/dist/codemods/utils/createTransformer.d.ts.map +1 -1
- package/dist/commands/add.d.ts +4 -4
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +8 -5
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/agent.d.ts +1 -2
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/create.d.ts +10 -11
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +26 -13
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/doctor.d.ts +9 -10
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/info.d.ts +3 -3
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +0 -1
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts +3 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts +1 -2
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +0 -1
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/update.d.ts +1 -2
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/upgrade.d.ts +3 -4
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/lib/agent-skill.d.ts +3 -4
- package/dist/lib/agent-skill.d.ts.map +1 -1
- package/dist/lib/create-project.d.ts +16 -11
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +27 -18
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/handle-cli-error.d.ts +1 -2
- package/dist/lib/handle-cli-error.d.ts.map +1 -1
- package/dist/lib/install-ai-sdk-lib.d.ts +1 -2
- package/dist/lib/install-ai-sdk-lib.d.ts.map +1 -1
- package/dist/lib/install-edge-lib.d.ts +1 -2
- package/dist/lib/install-edge-lib.d.ts.map +1 -1
- package/dist/lib/run-spawn.d.ts +6 -7
- package/dist/lib/run-spawn.d.ts.map +1 -1
- package/dist/lib/transform-options.d.ts +1 -2
- package/dist/lib/transform-options.d.ts.map +1 -1
- package/dist/lib/transform.d.ts +4 -5
- package/dist/lib/transform.d.ts.map +1 -1
- package/dist/lib/upgrade.d.ts +1 -2
- package/dist/lib/upgrade.d.ts.map +1 -1
- package/dist/lib/utils/config.d.ts +4 -5
- package/dist/lib/utils/config.d.ts.map +1 -1
- package/dist/lib/utils/file-scanner.d.ts +4 -5
- package/dist/lib/utils/file-scanner.d.ts.map +1 -1
- package/dist/lib/utils/logger.d.ts +1 -2
- package/dist/lib/utils/logger.d.ts.map +1 -1
- package/dist/lib/utils/package-installer.d.ts +2 -3
- package/dist/lib/utils/package-installer.d.ts.map +1 -1
- package/dist/lib/utils/package-json.d.ts +1 -2
- package/dist/lib/utils/package-json.d.ts.map +1 -1
- package/dist/lib/utils/package-manager.d.ts +7 -8
- package/dist/lib/utils/package-manager.d.ts.map +1 -1
- package/dist/lib/utils/registry.d.ts +5 -4
- package/dist/lib/utils/registry.d.ts.map +1 -1
- package/dist/lib/utils/registry.js +13 -2
- package/dist/lib/utils/registry.js.map +1 -1
- package/dist/lib/utils/workspace.d.ts +2 -3
- package/dist/lib/utils/workspace.d.ts.map +1 -1
- package/dist/program.d.ts +1 -2
- package/dist/program.d.ts.map +1 -1
- package/dist/run.d.ts +1 -2
- package/dist/run.d.ts.map +1 -1
- package/package.json +8 -7
- package/plugin/skills/assistant-ui/SKILL.md +3 -3
- package/src/commands/add.ts +10 -3
- package/src/commands/create.ts +33 -8
- package/src/commands/info.ts +0 -1
- package/src/commands/init.ts +1 -2
- package/src/commands/mcp.ts +0 -3
- package/src/lib/create-project.ts +35 -20
- package/src/lib/run-spawn.test.ts +0 -1
- package/src/lib/utils/registry.test.ts +56 -0
- package/src/lib/utils/registry.ts +35 -0
- package/src/run.test.ts +1 -5
package/src/commands/add.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Command } from "commander";
|
|
|
2
2
|
import { logger } from "../lib/utils/logger";
|
|
3
3
|
import { hasConfig } from "../lib/utils/config";
|
|
4
4
|
import {
|
|
5
|
+
detectRegistryPlatform,
|
|
5
6
|
getComponentsJsonStyle,
|
|
6
7
|
resolveRegistryItemUrl,
|
|
7
8
|
} from "../lib/utils/registry";
|
|
@@ -24,12 +25,13 @@ export function createAddComponentsPlan(params: {
|
|
|
24
25
|
overwrite?: boolean;
|
|
25
26
|
path?: string;
|
|
26
27
|
style?: string;
|
|
28
|
+
platform?: "web" | "native";
|
|
27
29
|
}): AddComponentsPlan {
|
|
28
30
|
const componentsToAdd = params.components.map((c) => {
|
|
29
31
|
if (!/^[a-zA-Z0-9-/]+$/.test(c)) {
|
|
30
32
|
throw new Error(`Invalid component name: ${c}`);
|
|
31
33
|
}
|
|
32
|
-
return resolveRegistryItemUrl(c, params.style);
|
|
34
|
+
return resolveRegistryItemUrl(c, params.style, params.platform);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
const [command, dlxArgs] = dlxCommand(params.packageManager);
|
|
@@ -61,21 +63,25 @@ export const add = new Command()
|
|
|
61
63
|
.option("--use-yarn", "explicitly use yarn")
|
|
62
64
|
.option("--use-bun", "explicitly use bun")
|
|
63
65
|
.action(async (components: string[], opts) => {
|
|
66
|
+
const platform = detectRegistryPlatform(opts.cwd);
|
|
67
|
+
|
|
64
68
|
// Check if project is initialized
|
|
65
69
|
if (!hasConfig(opts.cwd)) {
|
|
66
70
|
logger.warn(
|
|
67
|
-
|
|
71
|
+
`It looks like you haven't initialized your project yet. Defaulting to ${platform === "native" ? "the native component tree" : "Base UI flavored components"}. Run 'assistant-ui init' first for a configured setup.`,
|
|
68
72
|
);
|
|
69
73
|
logger.break();
|
|
70
74
|
}
|
|
71
75
|
|
|
76
|
+
logger.info(`Using the ${platform} registry tree.`);
|
|
72
77
|
logger.step(`Adding ${components.length} component(s)...`);
|
|
73
78
|
|
|
74
79
|
const packageManager = await resolvePackageManagerForCwd(
|
|
75
80
|
opts.cwd,
|
|
76
81
|
resolvePackageManager(opts),
|
|
77
82
|
);
|
|
78
|
-
const style =
|
|
83
|
+
const style =
|
|
84
|
+
platform === "web" ? getComponentsJsonStyle(opts.cwd) : undefined;
|
|
79
85
|
const { command, args } = createAddComponentsPlan({
|
|
80
86
|
components,
|
|
81
87
|
packageManager,
|
|
@@ -83,6 +89,7 @@ export const add = new Command()
|
|
|
83
89
|
overwrite: opts.overwrite,
|
|
84
90
|
path: opts.path,
|
|
85
91
|
...(style === undefined ? {} : { style }),
|
|
92
|
+
platform,
|
|
86
93
|
});
|
|
87
94
|
|
|
88
95
|
try {
|
package/src/commands/create.ts
CHANGED
|
@@ -195,7 +195,7 @@ export const PROJECT_METADATA: ProjectMetadata[] = [
|
|
|
195
195
|
description: "Expo / React Native",
|
|
196
196
|
category: "example",
|
|
197
197
|
path: "examples/with-expo",
|
|
198
|
-
hasLocalComponents:
|
|
198
|
+
hasLocalComponents: false,
|
|
199
199
|
},
|
|
200
200
|
{
|
|
201
201
|
name: "with-interactables",
|
|
@@ -282,8 +282,6 @@ export const PROJECT_METADATA: ProjectMetadata[] = [
|
|
|
282
282
|
// Examples that exist in the monorepo but are intentionally excluded from the CLI:
|
|
283
283
|
//
|
|
284
284
|
// - waterfall: Still in development, not ready for production.
|
|
285
|
-
// - with-cloud-standalone: For cloud without assistant-ui — not for the
|
|
286
|
-
// assistant-ui CLI.
|
|
287
285
|
// - with-store: In development, not ready for public use of the tap store.
|
|
288
286
|
// - with-tap-runtime: In development, not ready for public use of the tap
|
|
289
287
|
// store.
|
|
@@ -522,6 +520,12 @@ export const create = new Command()
|
|
|
522
520
|
.option("--skip-install", "skip installing packages")
|
|
523
521
|
.option("--skills", "add assistant-ui agent skills for AI coding assistants")
|
|
524
522
|
.option("--no-skills", "skip adding assistant-ui agent skills")
|
|
523
|
+
.addOption(
|
|
524
|
+
new Option(
|
|
525
|
+
"--cwd <cwd>",
|
|
526
|
+
"the working directory. defaults to the current directory.",
|
|
527
|
+
).hideHelp(),
|
|
528
|
+
)
|
|
525
529
|
.addOption(
|
|
526
530
|
new Option(
|
|
527
531
|
"--debug-source-root <path>",
|
|
@@ -577,9 +581,13 @@ export const create = new Command()
|
|
|
577
581
|
}
|
|
578
582
|
|
|
579
583
|
// Check directory
|
|
580
|
-
const absoluteProjectDir = path.resolve(
|
|
584
|
+
const absoluteProjectDir = path.resolve(
|
|
585
|
+
opts.cwd ?? process.cwd(),
|
|
586
|
+
resolvedProjectDirectory,
|
|
587
|
+
);
|
|
581
588
|
const { display: displayProjectDir, cdCommand } =
|
|
582
589
|
resolveProjectDirectoryGuidance({ absoluteProjectDir });
|
|
590
|
+
let projectDirExisted = true;
|
|
583
591
|
try {
|
|
584
592
|
const files = fs.readdirSync(absoluteProjectDir);
|
|
585
593
|
if (files.length > 0) {
|
|
@@ -593,6 +601,7 @@ export const create = new Command()
|
|
|
593
601
|
err instanceof Error ? (err as NodeJS.ErrnoException).code : undefined;
|
|
594
602
|
if (code === "ENOENT") {
|
|
595
603
|
// Directory doesn't exist — good, proceed
|
|
604
|
+
projectDirExisted = false;
|
|
596
605
|
} else if (code === "ENOTDIR") {
|
|
597
606
|
logger.error(
|
|
598
607
|
`${displayProjectDir} already exists and is not a directory`,
|
|
@@ -640,11 +649,24 @@ export const create = new Command()
|
|
|
640
649
|
);
|
|
641
650
|
|
|
642
651
|
// Clean up partial project directory on unexpected exit (e.g. Ctrl+C)
|
|
652
|
+
const resetProjectDir = () => {
|
|
653
|
+
if (!projectDirExisted) {
|
|
654
|
+
fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
if (!fs.existsSync(absoluteProjectDir)) return;
|
|
658
|
+
for (const entry of fs.readdirSync(absoluteProjectDir)) {
|
|
659
|
+
fs.rmSync(path.join(absoluteProjectDir, entry), {
|
|
660
|
+
recursive: true,
|
|
661
|
+
force: true,
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
};
|
|
643
665
|
let cleanupArmed = true;
|
|
644
666
|
const cleanupOnExit = () => {
|
|
645
667
|
if (!cleanupArmed) return;
|
|
646
668
|
cleanupArmed = false;
|
|
647
|
-
|
|
669
|
+
resetProjectDir();
|
|
648
670
|
};
|
|
649
671
|
const disarmCleanup = () => {
|
|
650
672
|
cleanupArmed = false;
|
|
@@ -653,8 +675,8 @@ export const create = new Command()
|
|
|
653
675
|
process.removeListener("SIGTERM", cleanupOnSignal);
|
|
654
676
|
};
|
|
655
677
|
// Node emits no "exit" when a signal kills the process. An in-flight
|
|
656
|
-
// runSpawn forwards the signal itself, so
|
|
657
|
-
//
|
|
678
|
+
// runSpawn forwards the signal itself, so cleanup runs on the error path
|
|
679
|
+
// once the child is reaped rather than while it is still writing.
|
|
658
680
|
const cleanupOnSignal = (signal: NodeJS.Signals) => {
|
|
659
681
|
if (hasActiveSpawn()) return;
|
|
660
682
|
cleanupOnExit();
|
|
@@ -698,7 +720,7 @@ export const create = new Command()
|
|
|
698
720
|
ref &&
|
|
699
721
|
!fs.existsSync(path.join(absoluteProjectDir, "package.json"))
|
|
700
722
|
) {
|
|
701
|
-
|
|
723
|
+
resetProjectDir();
|
|
702
724
|
logger.warn(
|
|
703
725
|
"Template not found at release tag, downloading from HEAD",
|
|
704
726
|
);
|
|
@@ -799,6 +821,9 @@ export const create = new Command()
|
|
|
799
821
|
logger.info(` ${cdCommand}`);
|
|
800
822
|
if (opts.skipInstall) {
|
|
801
823
|
logger.info(` ${pm} install`);
|
|
824
|
+
if (transformResult.registryInstallCommand) {
|
|
825
|
+
logger.info(` ${transformResult.registryInstallCommand}`);
|
|
826
|
+
}
|
|
802
827
|
}
|
|
803
828
|
logger.info(` # Set up your environment variables in ${envFile}`);
|
|
804
829
|
logger.info(` ${runCmd} ${devScript}`);
|
package/src/commands/info.ts
CHANGED
package/src/commands/init.ts
CHANGED
|
@@ -83,8 +83,7 @@ export const init = new Command()
|
|
|
83
83
|
logger.break();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const createArgs
|
|
87
|
-
if (projectDirectory) createArgs.push(targetDir);
|
|
86
|
+
const createArgs = projectDirectory ? [targetDir] : ["--cwd", cwd];
|
|
88
87
|
if (presetUrl) createArgs.push("--preset", presetUrl);
|
|
89
88
|
if (opts.useNpm) createArgs.push("--use-npm");
|
|
90
89
|
if (opts.usePnpm) createArgs.push("--use-pnpm");
|
package/src/commands/mcp.ts
CHANGED
|
@@ -75,9 +75,6 @@ const MCP_CONFIGS: Record<
|
|
|
75
75
|
if (process.platform === "win32") {
|
|
76
76
|
return path.join(process.env.APPDATA || "", "Zed", "settings.json");
|
|
77
77
|
}
|
|
78
|
-
if (process.platform === "darwin") {
|
|
79
|
-
return path.join(os.homedir(), ".zed", "settings.json");
|
|
80
|
-
}
|
|
81
78
|
return path.join(os.homedir(), ".config", "zed", "settings.json");
|
|
82
79
|
},
|
|
83
80
|
config: {
|
|
@@ -10,6 +10,10 @@ import { logger } from "./utils/logger";
|
|
|
10
10
|
import { runSpawn, SpawnExitError, SpawnSignalError } from "./run-spawn";
|
|
11
11
|
import { type PackageManagerName } from "./utils/package-manager";
|
|
12
12
|
import { readProjectFiles } from "./utils/file-scanner";
|
|
13
|
+
import {
|
|
14
|
+
detectRegistryPlatform,
|
|
15
|
+
resolveRegistryItemUrl,
|
|
16
|
+
} from "./utils/registry";
|
|
13
17
|
|
|
14
18
|
export function dlxCommand(pm: PackageManagerName): [string, string[]] {
|
|
15
19
|
switch (pm) {
|
|
@@ -186,6 +190,7 @@ export async function scaffoldProject(
|
|
|
186
190
|
|
|
187
191
|
export interface TransformResult {
|
|
188
192
|
registryInstallFailure?: { retryCommand: string };
|
|
193
|
+
registryInstallCommand?: string;
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
export async function transformProject(
|
|
@@ -199,29 +204,23 @@ export async function transformProject(
|
|
|
199
204
|
transformTsConfig(projectDir);
|
|
200
205
|
transformCssFiles(projectDir);
|
|
201
206
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (!opts.hasLocalComponents) {
|
|
206
|
-
const components = scanRequiredComponents(projectDir);
|
|
207
|
-
assistantUI = components.assistantUI;
|
|
208
|
-
shadcnUI = components.shadcnUI;
|
|
209
|
-
}
|
|
207
|
+
const components = opts.hasLocalComponents
|
|
208
|
+
? undefined
|
|
209
|
+
: resolveRegistryComponents(projectDir, scanRequiredComponents(projectDir));
|
|
210
210
|
|
|
211
211
|
const pm = opts.packageManager;
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
if (opts.skipInstall) {
|
|
213
|
+
if (!components) return {};
|
|
214
|
+
const [cmd, dlxArgs] = dlxCommand(pm);
|
|
215
|
+
return {
|
|
216
|
+
registryInstallCommand: `${cmd} ${[...dlxArgs, "shadcn@latest", "add", ...components].join(" ")}`,
|
|
217
|
+
};
|
|
215
218
|
}
|
|
216
219
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
assistantUI
|
|
222
|
-
) {
|
|
223
|
-
const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
|
|
224
|
-
const components = ["@assistant-ui/utils", ...shadcnUI, ...auiComponents];
|
|
220
|
+
logger.step("Installing dependencies...");
|
|
221
|
+
await installDependencies(projectDir, pm);
|
|
222
|
+
|
|
223
|
+
if (components) {
|
|
225
224
|
logger.step(`Installing components: ${components.join(", ")}...`);
|
|
226
225
|
const failure = await installShadcnRegistry(
|
|
227
226
|
projectDir,
|
|
@@ -235,6 +234,22 @@ export async function transformProject(
|
|
|
235
234
|
return {};
|
|
236
235
|
}
|
|
237
236
|
|
|
237
|
+
function resolveRegistryComponents(
|
|
238
|
+
projectDir: string,
|
|
239
|
+
{ assistantUI, shadcnUI }: RequiredComponents,
|
|
240
|
+
): string[] {
|
|
241
|
+
if (detectRegistryPlatform(projectDir) === "native") {
|
|
242
|
+
return ["utils", ...shadcnUI, ...assistantUI].map((component) =>
|
|
243
|
+
resolveRegistryItemUrl(component, undefined, "native"),
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return [
|
|
247
|
+
"@assistant-ui/utils",
|
|
248
|
+
...shadcnUI,
|
|
249
|
+
...assistantUI.map((component) => `@assistant-ui/${component}`),
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
|
|
238
253
|
function transformPackageJson(projectDir: string): void {
|
|
239
254
|
const pkgPath = path.join(projectDir, "package.json");
|
|
240
255
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
@@ -543,7 +558,7 @@ export async function reconcileAssistantUIImportLayout(
|
|
|
543
558
|
}
|
|
544
559
|
}
|
|
545
560
|
|
|
546
|
-
function scanRequiredComponents(projectDir: string): RequiredComponents {
|
|
561
|
+
export function scanRequiredComponents(projectDir: string): RequiredComponents {
|
|
547
562
|
const assistantUIComponents = new Set<string>();
|
|
548
563
|
const shadcnUIComponents = new Set<string>();
|
|
549
564
|
|
|
@@ -3,6 +3,7 @@ import * as os from "node:os";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
5
|
import {
|
|
6
|
+
detectRegistryPlatform,
|
|
6
7
|
getComponentsJsonStyle,
|
|
7
8
|
resolveQuickStartRegistryUrl,
|
|
8
9
|
resolveRegistryItemUrl,
|
|
@@ -61,6 +62,49 @@ describe("getComponentsJsonStyle", () => {
|
|
|
61
62
|
});
|
|
62
63
|
});
|
|
63
64
|
|
|
65
|
+
describe("detectRegistryPlatform", () => {
|
|
66
|
+
let cwd: string;
|
|
67
|
+
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
cwd = fs.mkdtempSync(path.join(os.tmpdir(), "assistant-ui-cli-"));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("detects react-native in dependencies", () => {
|
|
77
|
+
fs.writeFileSync(
|
|
78
|
+
path.join(cwd, "package.json"),
|
|
79
|
+
JSON.stringify({ dependencies: { "react-native": "0.86.3" } }),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(detectRegistryPlatform(cwd)).toBe("native");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("detects react-native in devDependencies", () => {
|
|
86
|
+
fs.writeFileSync(
|
|
87
|
+
path.join(cwd, "package.json"),
|
|
88
|
+
JSON.stringify({ devDependencies: { "react-native": "0.86.3" } }),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
expect(detectRegistryPlatform(cwd)).toBe("native");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("uses web without react-native", () => {
|
|
95
|
+
fs.writeFileSync(
|
|
96
|
+
path.join(cwd, "package.json"),
|
|
97
|
+
JSON.stringify({ dependencies: { react: "19.2.3" } }),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
expect(detectRegistryPlatform(cwd)).toBe("web");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("uses web when package.json is missing", () => {
|
|
104
|
+
expect(detectRegistryPlatform(cwd)).toBe("web");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
64
108
|
describe("resolveQuickStartRegistryUrl", () => {
|
|
65
109
|
it("uses the base quick start for base styles", () => {
|
|
66
110
|
expect(resolveQuickStartRegistryUrl("base-nova")).toBe(
|
|
@@ -111,4 +155,16 @@ describe("resolveRegistryItemUrl", () => {
|
|
|
111
155
|
"https://r.assistant-ui.com/styles/base-nova%3Fpreview%3D1/thread.json",
|
|
112
156
|
);
|
|
113
157
|
});
|
|
158
|
+
|
|
159
|
+
it("uses the native URL regardless of style", () => {
|
|
160
|
+
expect(resolveRegistryItemUrl("thread", "base-nova", "native")).toBe(
|
|
161
|
+
"https://r.assistant-ui.com/native/thread.json",
|
|
162
|
+
);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("keeps shared items at the root URL on native", () => {
|
|
166
|
+
expect(resolveRegistryItemUrl("utils", undefined, "native")).toBe(
|
|
167
|
+
"https://r.assistant-ui.com/utils.json",
|
|
168
|
+
);
|
|
169
|
+
});
|
|
114
170
|
});
|
|
@@ -2,6 +2,34 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
|
|
4
4
|
const REGISTRY_BASE_URL = "https://r.assistant-ui.com";
|
|
5
|
+
export const SHARED_REGISTRY_ITEMS = new Set(["utils"]);
|
|
6
|
+
|
|
7
|
+
export function detectRegistryPlatform(cwd: string): "web" | "native" {
|
|
8
|
+
try {
|
|
9
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
10
|
+
const packageJson = JSON.parse(
|
|
11
|
+
fs.readFileSync(packageJsonPath, "utf8"),
|
|
12
|
+
) as {
|
|
13
|
+
dependencies?: unknown;
|
|
14
|
+
devDependencies?: unknown;
|
|
15
|
+
};
|
|
16
|
+
const dependencyGroups = [
|
|
17
|
+
packageJson.dependencies,
|
|
18
|
+
packageJson.devDependencies,
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
return dependencyGroups.some(
|
|
22
|
+
(dependencies) =>
|
|
23
|
+
typeof dependencies === "object" &&
|
|
24
|
+
dependencies !== null &&
|
|
25
|
+
Object.hasOwn(dependencies, "react-native"),
|
|
26
|
+
)
|
|
27
|
+
? "native"
|
|
28
|
+
: "web";
|
|
29
|
+
} catch {
|
|
30
|
+
return "web";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
5
33
|
|
|
6
34
|
export function getComponentsJsonStyle(cwd: string): string | undefined {
|
|
7
35
|
try {
|
|
@@ -30,7 +58,14 @@ export function resolveQuickStartRegistryUrl(style?: string): string {
|
|
|
30
58
|
export function resolveRegistryItemUrl(
|
|
31
59
|
component: string,
|
|
32
60
|
style?: string,
|
|
61
|
+
platform: "web" | "native" = "web",
|
|
33
62
|
): string {
|
|
63
|
+
if (platform === "native") {
|
|
64
|
+
return SHARED_REGISTRY_ITEMS.has(component)
|
|
65
|
+
? `${REGISTRY_BASE_URL}/${encodeURIComponent(component)}.json`
|
|
66
|
+
: `${REGISTRY_BASE_URL}/native/${encodeURIComponent(component)}.json`;
|
|
67
|
+
}
|
|
68
|
+
|
|
34
69
|
if (style === undefined) {
|
|
35
70
|
return `${REGISTRY_BASE_URL}/base/${encodeURIComponent(component)}.json`;
|
|
36
71
|
}
|
package/src/run.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
|
|
3
3
|
const mocks = vi.hoisted(() => ({
|
|
4
4
|
parseAsync: vi.fn(),
|
|
@@ -13,10 +13,6 @@ vi.mock("./program", () => ({
|
|
|
13
13
|
import { runCli } from "./run";
|
|
14
14
|
|
|
15
15
|
describe("runCli", () => {
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.clearAllMocks();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
16
|
it("awaits and propagates asynchronous command failures", async () => {
|
|
21
17
|
const error = new Error("command failed");
|
|
22
18
|
mocks.parseAsync.mockRejectedValue(error);
|