@sansavision/aurora 0.1.0-alpha.20260212.4
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/README.md +4 -0
- package/package.json +17 -0
- package/src/ai-diagnostics.ts +156 -0
- package/src/ai.ts +574 -0
- package/src/analyze.ts +669 -0
- package/src/bin/aurora.ts +15 -0
- package/src/build.ts +431 -0
- package/src/bun-test-shims.d.ts +17 -0
- package/src/create-feature.ts +419 -0
- package/src/create-route.ts +581 -0
- package/src/create.ts +425 -0
- package/src/dev.ts +126 -0
- package/src/devtools.ts +1143 -0
- package/src/doctor.ts +611 -0
- package/src/explain.ts +855 -0
- package/src/help.ts +39 -0
- package/src/index.ts +34 -0
- package/src/init.ts +1011 -0
- package/src/inspect-cache.ts +464 -0
- package/src/lsp-inline-hints.ts +254 -0
- package/src/node-shims.d.ts +26 -0
- package/src/process.d.ts +11 -0
- package/src/query-profiler.ts +520 -0
- package/src/realtime-monitor.ts +389 -0
- package/src/registry.ts +303 -0
- package/src/run.ts +37 -0
- package/src/start.ts +56 -0
- package/src/test.ts +289 -0
- package/templates/basic/README.md +16 -0
- package/templates/basic/package.json +10 -0
- package/templates/basic/src/actions/createMessage.action.server.ts +22 -0
- package/templates/basic/src/lib/auth.server.ts +11 -0
- package/templates/basic/src/queries/listMessages.server.ts +17 -0
- package/templates/basic/src/routes/index.tsx +12 -0
- package/templates/blog/README.md +17 -0
- package/templates/blog/package.json +12 -0
- package/templates/blog/public/assets/og-default.svg +17 -0
- package/templates/blog/src/content/loadPosts.server.ts +22 -0
- package/templates/blog/src/content/posts/hello-world.md +11 -0
- package/templates/blog/src/content/posts/release-notes.md +9 -0
- package/templates/blog/src/routes/index.tsx +22 -0
- package/templates/blog/src/routes/posts/[slug].tsx +19 -0
- package/templates/blog/src/seo/meta.ts +19 -0
- package/templates/dashboard/README.md +18 -0
- package/templates/dashboard/package.json +10 -0
- package/templates/dashboard/src/actions/acknowledgeAlert.action.server.ts +6 -0
- package/templates/dashboard/src/queries/getDashboardMetrics.server.ts +30 -0
- package/templates/dashboard/src/realtime/useDashboardRealtime.client.ts +13 -0
- package/templates/dashboard/src/routes/index.tsx +19 -0
- package/templates/dashboard/src/widgets/DataGrid.client.ts +8 -0
- package/templates/dashboard/src/widgets/MetricChart.client.ts +8 -0
- package/templates/desktop/README.md +18 -0
- package/templates/desktop/package.json +11 -0
- package/templates/desktop/src/actions/saveDesktopPreference.action.server.ts +28 -0
- package/templates/desktop/src/desktop/secureStorage.client.ts +20 -0
- package/templates/desktop/src/desktop/tauriBridge.client.ts +14 -0
- package/templates/desktop/src/queries/getDesktopSyncStatus.server.ts +9 -0
- package/templates/desktop/src/routes/index.tsx +27 -0
- package/templates/desktop/src/sync/offlineSyncBoundary.server.ts +27 -0
- package/templates/feature-skeleton/README.md +13 -0
- package/templates/feature-skeleton/actions/createFeature.action.server.ts +19 -0
- package/templates/feature-skeleton/index.ts +8 -0
- package/templates/feature-skeleton/queries/listFeature.server.ts +15 -0
- package/templates/feature-skeleton/realtime/useFeatureRealtime.client.ts +16 -0
- package/templates/feature-skeleton/template.manifest.json +15 -0
- package/templates/feature-skeleton/ui/FeatureView.client.tsx +14 -0
- package/templates/mobile/README.md +17 -0
- package/templates/mobile/package.json +11 -0
- package/templates/mobile/src/mobile/auth/session-handoff.client.ts +69 -0
- package/templates/mobile/src/mobile/generated/mobile-api-sdk.ts +62 -0
- package/templates/mobile/src/mobile/transport/mobile-api-transport.client.ts +122 -0
- package/templates/mobile/src/routes/index.tsx +134 -0
- package/templates/monorepo/README.md +18 -0
- package/templates/monorepo/apps/web/package.json +9 -0
- package/templates/monorepo/apps/web/src/routes/index.tsx +1 -0
- package/templates/monorepo/package.json +13 -0
- package/templates/monorepo/packages/shared/README.md +3 -0
- package/templates/monorepo/packages/ui/README.md +3 -0
- package/templates/saas/README.md +17 -0
- package/templates/saas/package.json +10 -0
- package/templates/saas/src/admin/getDashboard.server.ts +18 -0
- package/templates/saas/src/auth/session.server.ts +13 -0
- package/templates/saas/src/billing/checkout.server.ts +11 -0
- package/templates/saas/src/email/sendWelcome.server.ts +8 -0
- package/templates/saas/src/realtime/notifications.server.ts +8 -0
- package/templates/saas/src/routes/index.tsx +20 -0
- package/test/ai.test.ts +94 -0
- package/test/analyze.test.ts +301 -0
- package/test/build.test.ts +135 -0
- package/test/create-feature.test.ts +145 -0
- package/test/create-route.test.ts +117 -0
- package/test/create.test.ts +222 -0
- package/test/dev.test.ts +52 -0
- package/test/devtools.test.ts +130 -0
- package/test/doctor.test.ts +129 -0
- package/test/explain.test.ts +232 -0
- package/test/feature-skeleton.test.ts +53 -0
- package/test/fixtures/analyze/cache-input.invalid.json +1 -0
- package/test/fixtures/analyze/cache-input.missing-keyhash.v1.json +10 -0
- package/test/fixtures/analyze/cache-input.unsupported-version.v2.json +10 -0
- package/test/fixtures/analyze/cache-input.v1.json +12 -0
- package/test/fixtures/analyze/compiler-manifest/manifest.json +11 -0
- package/test/fixtures/analyze/guardrails-input.unsupported-version.v2.json +4 -0
- package/test/fixtures/analyze/guardrails-input.v1.json +49 -0
- package/test/fixtures/analyze/query-input.invalid-cache-status.v1.json +11 -0
- package/test/fixtures/analyze/query-input.unsupported-version.v2.json +11 -0
- package/test/fixtures/analyze/query-input.v1.json +18 -0
- package/test/fixtures/analyze/realtime-input.missing-lag-p95.v1.json +10 -0
- package/test/fixtures/analyze/realtime-input.unsupported-version.v2.json +8 -0
- package/test/fixtures/analyze/realtime-input.v1.json +12 -0
- package/test/fixtures/cache-inspector/cache-input.v1.json +23 -0
- package/test/fixtures/cache-inspector/invalid.json +1 -0
- package/test/fixtures/cache-inspector/snapshot.v1.json +34 -0
- package/test/fixtures/cache-inspector/unsupported-version.v2.json +13 -0
- package/test/fixtures/devtools/healthy.v1.json +130 -0
- package/test/fixtures/devtools/invalid.json +1 -0
- package/test/fixtures/devtools/unsupported-version.v2.json +8 -0
- package/test/fixtures/devtools/warn.v1.json +114 -0
- package/test/fixtures/doctor/clean/src/page.tsx +3 -0
- package/test/fixtures/doctor/findings/src/accessibility.client.tsx +7 -0
- package/test/fixtures/doctor/findings/src/migration.config.ts +3 -0
- package/test/fixtures/doctor/findings/src/page.client.tsx +5 -0
- package/test/fixtures/doctor/findings/src/perf.server.ts +15 -0
- package/test/fixtures/doctor/findings/src/routes.js +3 -0
- package/test/fixtures/doctor/findings/src/security.server.ts +7 -0
- package/test/fixtures/doctor/findings/src/users.server.ts +3 -0
- package/test/fixtures/doctor/governance/src/features/analytics/OWNERS.ts +2 -0
- package/test/fixtures/doctor/governance/src/features/analytics/page.tsx +3 -0
- package/test/fixtures/doctor/governance/src/features/billing/page.tsx +3 -0
- package/test/fixtures/explain/invalid.json +1 -0
- package/test/fixtures/explain/module-report.unsupported-version.v2.json +6 -0
- package/test/fixtures/explain/module-report.v1.json +72 -0
- package/test/fixtures/query-profiler/healthy.v1.json +11 -0
- package/test/fixtures/query-profiler/invalid.json +1 -0
- package/test/fixtures/query-profiler/unsupported-version.v2.json +6 -0
- package/test/fixtures/query-profiler/warning.v1.json +10 -0
- package/test/fixtures/realtime-monitor/healthy.v1.json +8 -0
- package/test/fixtures/realtime-monitor/invalid.json +1 -0
- package/test/fixtures/realtime-monitor/unsupported-version.v2.json +8 -0
- package/test/fixtures/realtime-monitor/warning.v1.json +8 -0
- package/test/help-parity.test.ts +104 -0
- package/test/init.test.ts +164 -0
- package/test/inspect-cache.test.ts +112 -0
- package/test/lsp-inline-hints.test.ts +65 -0
- package/test/query-profiler.test.ts +123 -0
- package/test/realtime-monitor.test.ts +115 -0
- package/test/registry.test.ts +41 -0
- package/test/start.test.ts +23 -0
- package/test/test-command.test.ts +65 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readSessionToken, writeSessionToken } from "../mobile/auth/session-handoff.client";
|
|
2
|
+
import { createMobileApiClient } from "../mobile/generated/mobile-api-sdk";
|
|
3
|
+
import { createHttpMobileTransport } from "../mobile/transport/mobile-api-transport.client";
|
|
4
|
+
|
|
5
|
+
export async function HomePage(): Promise<string> {
|
|
6
|
+
const existingToken = readSessionToken();
|
|
7
|
+
if (!existingToken) {
|
|
8
|
+
writeSessionToken("mobile-demo-token", Date.now() + 1000 * 60 * 30);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const transport = createHttpMobileTransport({
|
|
12
|
+
baseUrl: "https://mobile.local.test",
|
|
13
|
+
retries: 2,
|
|
14
|
+
retryDelayMs: 10,
|
|
15
|
+
fetchImpl: createMockMobileFetch(),
|
|
16
|
+
});
|
|
17
|
+
const client = createMobileApiClient(transport);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const messages = await client.queries["messages.list"]({
|
|
21
|
+
cursor: null,
|
|
22
|
+
limit: 20,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (messages.items.length === 0) {
|
|
26
|
+
await client.actions["messages.create"]({
|
|
27
|
+
text: "Hello from Aurora mobile starter.",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return [
|
|
32
|
+
"<main>",
|
|
33
|
+
"<h1>Aurora Mobile Companion Starter</h1>",
|
|
34
|
+
`<p>message_count: ${messages.items.length}</p>`,
|
|
35
|
+
"<p>network_retry_policy: exponential backoff</p>",
|
|
36
|
+
"</main>",
|
|
37
|
+
].join("");
|
|
38
|
+
} catch (error) {
|
|
39
|
+
const message = error instanceof Error ? error.message : "unknown mobile error";
|
|
40
|
+
|
|
41
|
+
return [
|
|
42
|
+
"<main>",
|
|
43
|
+
"<h1>Aurora Mobile Companion Starter</h1>",
|
|
44
|
+
`<p>sync_status: degraded</p>`,
|
|
45
|
+
`<p>error: ${message}</p>`,
|
|
46
|
+
"<p>retry_hint: check connectivity and retry queued operations.</p>",
|
|
47
|
+
"</main>",
|
|
48
|
+
].join("");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function createMockMobileFetch(): typeof fetch {
|
|
53
|
+
const attempts = new Map<string, number>();
|
|
54
|
+
|
|
55
|
+
return async (_input, init): Promise<Response> => {
|
|
56
|
+
const rawBody = typeof init?.body === "string" ? init.body : "{}";
|
|
57
|
+
const payload = JSON.parse(rawBody) as {
|
|
58
|
+
operation?: string;
|
|
59
|
+
name?: string;
|
|
60
|
+
input?: {
|
|
61
|
+
text?: string;
|
|
62
|
+
};
|
|
63
|
+
params?: {
|
|
64
|
+
cursor?: string | null;
|
|
65
|
+
limit?: number;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const operation = payload.operation ?? "unknown";
|
|
70
|
+
const name = payload.name ?? "unknown";
|
|
71
|
+
const key = `${operation}:${name}`;
|
|
72
|
+
const attempt = (attempts.get(key) ?? 0) + 1;
|
|
73
|
+
attempts.set(key, attempt);
|
|
74
|
+
|
|
75
|
+
if (attempt === 1) {
|
|
76
|
+
throw new Error("simulated transient network error");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (operation === "query" && name === "messages.list") {
|
|
80
|
+
return new Response(
|
|
81
|
+
JSON.stringify({
|
|
82
|
+
data: {
|
|
83
|
+
items: [
|
|
84
|
+
{
|
|
85
|
+
id: "seed-1",
|
|
86
|
+
text: "Welcome to Aurora mobile starter.",
|
|
87
|
+
createdAt: 1707609600000,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
nextCursor: null,
|
|
91
|
+
},
|
|
92
|
+
tags: ["messages"],
|
|
93
|
+
}),
|
|
94
|
+
{
|
|
95
|
+
status: 200,
|
|
96
|
+
headers: {
|
|
97
|
+
"content-type": "application/json",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (operation === "action" && name === "messages.create") {
|
|
104
|
+
return new Response(
|
|
105
|
+
JSON.stringify({
|
|
106
|
+
data: {
|
|
107
|
+
id: "msg-1",
|
|
108
|
+
text: payload.input?.text ?? "",
|
|
109
|
+
createdAt: Date.now(),
|
|
110
|
+
},
|
|
111
|
+
tags: ["messages"],
|
|
112
|
+
}),
|
|
113
|
+
{
|
|
114
|
+
status: 200,
|
|
115
|
+
headers: {
|
|
116
|
+
"content-type": "application/json",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return new Response(
|
|
123
|
+
JSON.stringify({
|
|
124
|
+
error: "unknown mobile operation",
|
|
125
|
+
}),
|
|
126
|
+
{
|
|
127
|
+
status: 404,
|
|
128
|
+
headers: {
|
|
129
|
+
"content-type": "application/json",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# __AURORA_APP_NAME__
|
|
2
|
+
|
|
3
|
+
Template: monorepo
|
|
4
|
+
|
|
5
|
+
Aurora monorepo starter template.
|
|
6
|
+
|
|
7
|
+
Includes:
|
|
8
|
+
|
|
9
|
+
- workspace root with shared scripts
|
|
10
|
+
- `apps/web` application package
|
|
11
|
+
- `packages/ui` shared UI package
|
|
12
|
+
- `packages/shared` shared utilities/types package
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
|
|
16
|
+
- `bun run dev`
|
|
17
|
+
- `bun run build`
|
|
18
|
+
- `bun run start`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const HomePage = () => "<main>Aurora monorepo starter web app.</main>";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__AURORA_APP_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"workspaces": [
|
|
5
|
+
"apps/*",
|
|
6
|
+
"packages/*"
|
|
7
|
+
],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "bun run --cwd apps/web aurora dev",
|
|
10
|
+
"build": "bun run --cwd apps/web aurora build",
|
|
11
|
+
"start": "bun run --cwd apps/web aurora start"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# __AURORA_APP_NAME__
|
|
2
|
+
|
|
3
|
+
Aurora SaaS starter template.
|
|
4
|
+
|
|
5
|
+
Includes:
|
|
6
|
+
|
|
7
|
+
- session/auth seam
|
|
8
|
+
- billing checkout seam
|
|
9
|
+
- admin dashboard query
|
|
10
|
+
- realtime notifications publisher/subscriber seam
|
|
11
|
+
- transactional email seam
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
- `aurora dev`
|
|
16
|
+
- `aurora build`
|
|
17
|
+
- `aurora start`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface DashboardSummary {
|
|
2
|
+
projectCount: number;
|
|
3
|
+
activeSeats: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export async function getAdminDashboard(ownerId: string): Promise<DashboardSummary> {
|
|
7
|
+
if (!ownerId) {
|
|
8
|
+
return {
|
|
9
|
+
projectCount: 0,
|
|
10
|
+
activeSeats: 0,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
projectCount: 3,
|
|
16
|
+
activeSeats: 12,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CheckoutSession {
|
|
2
|
+
id: string;
|
|
3
|
+
checkoutUrl: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export async function createCheckoutSession(userId: string): Promise<CheckoutSession> {
|
|
7
|
+
return {
|
|
8
|
+
id: `checkout-${userId}`,
|
|
9
|
+
checkoutUrl: `https://billing.local/checkout/${userId}`,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getAdminDashboard } from "../admin/getDashboard.server";
|
|
2
|
+
import { createCheckoutSession } from "../billing/checkout.server";
|
|
3
|
+
import { sendWelcomeEmail } from "../email/sendWelcome.server";
|
|
4
|
+
import { publishNotification } from "../realtime/notifications.server";
|
|
5
|
+
import { getSessionUser } from "../auth/session.server";
|
|
6
|
+
|
|
7
|
+
export async function HomePage(): Promise<string> {
|
|
8
|
+
const user = await getSessionUser();
|
|
9
|
+
const dashboard = await getAdminDashboard(user.id);
|
|
10
|
+
|
|
11
|
+
await sendWelcomeEmail({ userId: user.id, email: user.email });
|
|
12
|
+
await publishNotification({
|
|
13
|
+
userId: user.id,
|
|
14
|
+
message: "Welcome to Aurora SaaS starter",
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const checkout = await createCheckoutSession(user.id);
|
|
18
|
+
|
|
19
|
+
return `<main><h1>Aurora SaaS Starter</h1><p>projects: ${dashboard.projectCount}</p><p>checkout: ${checkout.checkoutUrl}</p></main>`;
|
|
20
|
+
}
|
package/test/ai.test.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { describe, expect, it } from "bun:test";
|
|
5
|
+
|
|
6
|
+
import { runAuroraCli } from "../src";
|
|
7
|
+
|
|
8
|
+
let tempCounter = 1;
|
|
9
|
+
|
|
10
|
+
function uniqueTempPath(suffix: string): string {
|
|
11
|
+
tempCounter += 1;
|
|
12
|
+
return `/tmp/aurora-cli-ai-${suffix}-${Date.now()}-${tempCounter}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("aurora ai", () => {
|
|
16
|
+
it("infers scaffold plan in dry-run JSON mode", () => {
|
|
17
|
+
const cwd = uniqueTempPath("dry-run");
|
|
18
|
+
mkdirSync(cwd, { recursive: true });
|
|
19
|
+
|
|
20
|
+
const result = runAuroraCli(
|
|
21
|
+
[
|
|
22
|
+
"ai",
|
|
23
|
+
"add",
|
|
24
|
+
"a",
|
|
25
|
+
"guestbook",
|
|
26
|
+
"feature",
|
|
27
|
+
"with",
|
|
28
|
+
"reactions",
|
|
29
|
+
"and",
|
|
30
|
+
"moderation",
|
|
31
|
+
"--dry-run",
|
|
32
|
+
"--format",
|
|
33
|
+
"json",
|
|
34
|
+
],
|
|
35
|
+
{ cwd },
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
expect(result.exitCode).toBe(0);
|
|
39
|
+
|
|
40
|
+
const parsed = JSON.parse(result.stdout ?? "{}") as {
|
|
41
|
+
mode?: string;
|
|
42
|
+
dryRun?: boolean;
|
|
43
|
+
inferred?: {
|
|
44
|
+
featureSlug?: string;
|
|
45
|
+
routeKind?: string;
|
|
46
|
+
routeDataSource?: string;
|
|
47
|
+
routeAuth?: string;
|
|
48
|
+
};
|
|
49
|
+
diagnostics?: Array<{ code?: string }>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
expect(parsed.mode).toBe("ai");
|
|
53
|
+
expect(parsed.dryRun).toBe(true);
|
|
54
|
+
expect(parsed.inferred?.featureSlug).toBe("guestbook-reactions-moderation");
|
|
55
|
+
expect(parsed.inferred?.routeKind).toBe("crud");
|
|
56
|
+
expect(parsed.inferred?.routeDataSource).toBe("database");
|
|
57
|
+
expect(parsed.inferred?.routeAuth).toBe("admin");
|
|
58
|
+
expect(parsed.diagnostics?.length).toBe(0);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("executes create-feature scaffold when not in dry-run mode", () => {
|
|
62
|
+
const cwd = uniqueTempPath("scaffold");
|
|
63
|
+
mkdirSync(cwd, { recursive: true });
|
|
64
|
+
|
|
65
|
+
const result = runAuroraCli(["ai", "guestbook", "moderation"], { cwd });
|
|
66
|
+
|
|
67
|
+
expect(result.exitCode).toBe(0);
|
|
68
|
+
expect(result.stdout).toContain("aurora ai bootstrap");
|
|
69
|
+
expect(result.stdout).toContain("scaffold_output:");
|
|
70
|
+
expect(existsSync(join(cwd, "src/features/guestbook-moderation"))).toBe(true);
|
|
71
|
+
expect(existsSync(join(cwd, "src/routes/guestbook-moderation/page.tsx"))).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("returns AI-readable diagnostic when prompt is underspecified", () => {
|
|
75
|
+
const cwd = uniqueTempPath("underspecified");
|
|
76
|
+
mkdirSync(cwd, { recursive: true });
|
|
77
|
+
|
|
78
|
+
const result = runAuroraCli(["ai", "build", "feature", "--dry-run", "--format", "json"], {
|
|
79
|
+
cwd,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
expect(result.exitCode).toBe(0);
|
|
83
|
+
|
|
84
|
+
const parsed = JSON.parse(result.stdout ?? "{}") as {
|
|
85
|
+
inferred?: { featureSlug?: string };
|
|
86
|
+
diagnostics?: Array<{ code?: string; why?: string; howToFix?: string }>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
expect(parsed.inferred?.featureSlug).toBe("ai-feature");
|
|
90
|
+
expect(parsed.diagnostics?.some((issue) => issue.code === "AI_PROMPT_UNDERSPECIFIED")).toBe(true);
|
|
91
|
+
expect(parsed.diagnostics?.every((issue) => Boolean(issue.why))).toBe(true);
|
|
92
|
+
expect(parsed.diagnostics?.every((issue) => Boolean(issue.howToFix))).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
});
|