@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.
Files changed (150) hide show
  1. package/README.md +4 -0
  2. package/package.json +17 -0
  3. package/src/ai-diagnostics.ts +156 -0
  4. package/src/ai.ts +574 -0
  5. package/src/analyze.ts +669 -0
  6. package/src/bin/aurora.ts +15 -0
  7. package/src/build.ts +431 -0
  8. package/src/bun-test-shims.d.ts +17 -0
  9. package/src/create-feature.ts +419 -0
  10. package/src/create-route.ts +581 -0
  11. package/src/create.ts +425 -0
  12. package/src/dev.ts +126 -0
  13. package/src/devtools.ts +1143 -0
  14. package/src/doctor.ts +611 -0
  15. package/src/explain.ts +855 -0
  16. package/src/help.ts +39 -0
  17. package/src/index.ts +34 -0
  18. package/src/init.ts +1011 -0
  19. package/src/inspect-cache.ts +464 -0
  20. package/src/lsp-inline-hints.ts +254 -0
  21. package/src/node-shims.d.ts +26 -0
  22. package/src/process.d.ts +11 -0
  23. package/src/query-profiler.ts +520 -0
  24. package/src/realtime-monitor.ts +389 -0
  25. package/src/registry.ts +303 -0
  26. package/src/run.ts +37 -0
  27. package/src/start.ts +56 -0
  28. package/src/test.ts +289 -0
  29. package/templates/basic/README.md +16 -0
  30. package/templates/basic/package.json +10 -0
  31. package/templates/basic/src/actions/createMessage.action.server.ts +22 -0
  32. package/templates/basic/src/lib/auth.server.ts +11 -0
  33. package/templates/basic/src/queries/listMessages.server.ts +17 -0
  34. package/templates/basic/src/routes/index.tsx +12 -0
  35. package/templates/blog/README.md +17 -0
  36. package/templates/blog/package.json +12 -0
  37. package/templates/blog/public/assets/og-default.svg +17 -0
  38. package/templates/blog/src/content/loadPosts.server.ts +22 -0
  39. package/templates/blog/src/content/posts/hello-world.md +11 -0
  40. package/templates/blog/src/content/posts/release-notes.md +9 -0
  41. package/templates/blog/src/routes/index.tsx +22 -0
  42. package/templates/blog/src/routes/posts/[slug].tsx +19 -0
  43. package/templates/blog/src/seo/meta.ts +19 -0
  44. package/templates/dashboard/README.md +18 -0
  45. package/templates/dashboard/package.json +10 -0
  46. package/templates/dashboard/src/actions/acknowledgeAlert.action.server.ts +6 -0
  47. package/templates/dashboard/src/queries/getDashboardMetrics.server.ts +30 -0
  48. package/templates/dashboard/src/realtime/useDashboardRealtime.client.ts +13 -0
  49. package/templates/dashboard/src/routes/index.tsx +19 -0
  50. package/templates/dashboard/src/widgets/DataGrid.client.ts +8 -0
  51. package/templates/dashboard/src/widgets/MetricChart.client.ts +8 -0
  52. package/templates/desktop/README.md +18 -0
  53. package/templates/desktop/package.json +11 -0
  54. package/templates/desktop/src/actions/saveDesktopPreference.action.server.ts +28 -0
  55. package/templates/desktop/src/desktop/secureStorage.client.ts +20 -0
  56. package/templates/desktop/src/desktop/tauriBridge.client.ts +14 -0
  57. package/templates/desktop/src/queries/getDesktopSyncStatus.server.ts +9 -0
  58. package/templates/desktop/src/routes/index.tsx +27 -0
  59. package/templates/desktop/src/sync/offlineSyncBoundary.server.ts +27 -0
  60. package/templates/feature-skeleton/README.md +13 -0
  61. package/templates/feature-skeleton/actions/createFeature.action.server.ts +19 -0
  62. package/templates/feature-skeleton/index.ts +8 -0
  63. package/templates/feature-skeleton/queries/listFeature.server.ts +15 -0
  64. package/templates/feature-skeleton/realtime/useFeatureRealtime.client.ts +16 -0
  65. package/templates/feature-skeleton/template.manifest.json +15 -0
  66. package/templates/feature-skeleton/ui/FeatureView.client.tsx +14 -0
  67. package/templates/mobile/README.md +17 -0
  68. package/templates/mobile/package.json +11 -0
  69. package/templates/mobile/src/mobile/auth/session-handoff.client.ts +69 -0
  70. package/templates/mobile/src/mobile/generated/mobile-api-sdk.ts +62 -0
  71. package/templates/mobile/src/mobile/transport/mobile-api-transport.client.ts +122 -0
  72. package/templates/mobile/src/routes/index.tsx +134 -0
  73. package/templates/monorepo/README.md +18 -0
  74. package/templates/monorepo/apps/web/package.json +9 -0
  75. package/templates/monorepo/apps/web/src/routes/index.tsx +1 -0
  76. package/templates/monorepo/package.json +13 -0
  77. package/templates/monorepo/packages/shared/README.md +3 -0
  78. package/templates/monorepo/packages/ui/README.md +3 -0
  79. package/templates/saas/README.md +17 -0
  80. package/templates/saas/package.json +10 -0
  81. package/templates/saas/src/admin/getDashboard.server.ts +18 -0
  82. package/templates/saas/src/auth/session.server.ts +13 -0
  83. package/templates/saas/src/billing/checkout.server.ts +11 -0
  84. package/templates/saas/src/email/sendWelcome.server.ts +8 -0
  85. package/templates/saas/src/realtime/notifications.server.ts +8 -0
  86. package/templates/saas/src/routes/index.tsx +20 -0
  87. package/test/ai.test.ts +94 -0
  88. package/test/analyze.test.ts +301 -0
  89. package/test/build.test.ts +135 -0
  90. package/test/create-feature.test.ts +145 -0
  91. package/test/create-route.test.ts +117 -0
  92. package/test/create.test.ts +222 -0
  93. package/test/dev.test.ts +52 -0
  94. package/test/devtools.test.ts +130 -0
  95. package/test/doctor.test.ts +129 -0
  96. package/test/explain.test.ts +232 -0
  97. package/test/feature-skeleton.test.ts +53 -0
  98. package/test/fixtures/analyze/cache-input.invalid.json +1 -0
  99. package/test/fixtures/analyze/cache-input.missing-keyhash.v1.json +10 -0
  100. package/test/fixtures/analyze/cache-input.unsupported-version.v2.json +10 -0
  101. package/test/fixtures/analyze/cache-input.v1.json +12 -0
  102. package/test/fixtures/analyze/compiler-manifest/manifest.json +11 -0
  103. package/test/fixtures/analyze/guardrails-input.unsupported-version.v2.json +4 -0
  104. package/test/fixtures/analyze/guardrails-input.v1.json +49 -0
  105. package/test/fixtures/analyze/query-input.invalid-cache-status.v1.json +11 -0
  106. package/test/fixtures/analyze/query-input.unsupported-version.v2.json +11 -0
  107. package/test/fixtures/analyze/query-input.v1.json +18 -0
  108. package/test/fixtures/analyze/realtime-input.missing-lag-p95.v1.json +10 -0
  109. package/test/fixtures/analyze/realtime-input.unsupported-version.v2.json +8 -0
  110. package/test/fixtures/analyze/realtime-input.v1.json +12 -0
  111. package/test/fixtures/cache-inspector/cache-input.v1.json +23 -0
  112. package/test/fixtures/cache-inspector/invalid.json +1 -0
  113. package/test/fixtures/cache-inspector/snapshot.v1.json +34 -0
  114. package/test/fixtures/cache-inspector/unsupported-version.v2.json +13 -0
  115. package/test/fixtures/devtools/healthy.v1.json +130 -0
  116. package/test/fixtures/devtools/invalid.json +1 -0
  117. package/test/fixtures/devtools/unsupported-version.v2.json +8 -0
  118. package/test/fixtures/devtools/warn.v1.json +114 -0
  119. package/test/fixtures/doctor/clean/src/page.tsx +3 -0
  120. package/test/fixtures/doctor/findings/src/accessibility.client.tsx +7 -0
  121. package/test/fixtures/doctor/findings/src/migration.config.ts +3 -0
  122. package/test/fixtures/doctor/findings/src/page.client.tsx +5 -0
  123. package/test/fixtures/doctor/findings/src/perf.server.ts +15 -0
  124. package/test/fixtures/doctor/findings/src/routes.js +3 -0
  125. package/test/fixtures/doctor/findings/src/security.server.ts +7 -0
  126. package/test/fixtures/doctor/findings/src/users.server.ts +3 -0
  127. package/test/fixtures/doctor/governance/src/features/analytics/OWNERS.ts +2 -0
  128. package/test/fixtures/doctor/governance/src/features/analytics/page.tsx +3 -0
  129. package/test/fixtures/doctor/governance/src/features/billing/page.tsx +3 -0
  130. package/test/fixtures/explain/invalid.json +1 -0
  131. package/test/fixtures/explain/module-report.unsupported-version.v2.json +6 -0
  132. package/test/fixtures/explain/module-report.v1.json +72 -0
  133. package/test/fixtures/query-profiler/healthy.v1.json +11 -0
  134. package/test/fixtures/query-profiler/invalid.json +1 -0
  135. package/test/fixtures/query-profiler/unsupported-version.v2.json +6 -0
  136. package/test/fixtures/query-profiler/warning.v1.json +10 -0
  137. package/test/fixtures/realtime-monitor/healthy.v1.json +8 -0
  138. package/test/fixtures/realtime-monitor/invalid.json +1 -0
  139. package/test/fixtures/realtime-monitor/unsupported-version.v2.json +8 -0
  140. package/test/fixtures/realtime-monitor/warning.v1.json +8 -0
  141. package/test/help-parity.test.ts +104 -0
  142. package/test/init.test.ts +164 -0
  143. package/test/inspect-cache.test.ts +112 -0
  144. package/test/lsp-inline-hints.test.ts +65 -0
  145. package/test/query-profiler.test.ts +123 -0
  146. package/test/realtime-monitor.test.ts +115 -0
  147. package/test/registry.test.ts +41 -0
  148. package/test/start.test.ts +23 -0
  149. package/test/test-command.test.ts +65 -0
  150. package/tsconfig.json +19 -0
@@ -0,0 +1,112 @@
1
+ import { join } from "node:path";
2
+
3
+ import { describe, expect, it } from "bun:test";
4
+
5
+ import { runAuroraCli } from "../src";
6
+
7
+ const projectRoot = join(import.meta.dir, "..");
8
+
9
+ function fixturePath(name: string): string {
10
+ return join("test/fixtures/cache-inspector", name);
11
+ }
12
+
13
+ describe("aurora inspect-cache", () => {
14
+ it("renders a text report for cache snapshot input", () => {
15
+ const result = runAuroraCli(
16
+ ["inspect-cache", "--input", fixturePath("snapshot.v1.json")],
17
+ { cwd: projectRoot },
18
+ );
19
+
20
+ expect(result.exitCode).toBe(0);
21
+ expect(result.stdout).toContain("aurora cache inspector report");
22
+ expect(result.stdout).toContain("entries_total: 3");
23
+ expect(result.stdout).toContain("entries_filtered: 3");
24
+ expect(result.stdout).toContain("stale_entries: 1");
25
+ expect(result.stdout).toContain("largest_entries:");
26
+ });
27
+
28
+ it("supports json output with tag filtering and row limits", () => {
29
+ const result = runAuroraCli(
30
+ [
31
+ "inspect-cache",
32
+ "--input",
33
+ fixturePath("cache-input.v1.json"),
34
+ "--tag",
35
+ "users",
36
+ "--limit",
37
+ "1",
38
+ "--format",
39
+ "json",
40
+ ],
41
+ { cwd: projectRoot },
42
+ );
43
+
44
+ expect(result.exitCode).toBe(0);
45
+ const parsed = JSON.parse(result.stdout ?? "{}") as {
46
+ mode?: string;
47
+ entries?: number;
48
+ filteredEntries?: number;
49
+ staleEntries?: number;
50
+ topTags?: Array<{ tag?: string; entries?: number }>;
51
+ largestEntries?: Array<{ key?: string; sizeBytes?: number }>;
52
+ };
53
+
54
+ expect(parsed.mode).toBe("cache-inspector");
55
+ expect(parsed.entries).toBe(3);
56
+ expect(parsed.filteredEntries).toBe(2);
57
+ expect(parsed.staleEntries).toBe(1);
58
+ expect(parsed.topTags?.[0]?.tag).toBe("users");
59
+ expect(parsed.topTags?.[0]?.entries).toBe(2);
60
+ expect(parsed.largestEntries?.length).toBe(1);
61
+ expect(parsed.largestEntries?.[0]?.key).toBe("users:u2");
62
+ expect(parsed.largestEntries?.[0]?.sizeBytes).toBe(256);
63
+ });
64
+
65
+ it("requires --input", () => {
66
+ const result = runAuroraCli(["inspect-cache"], { cwd: projectRoot });
67
+
68
+ expect(result.exitCode).toBe(2);
69
+ expect(result.stderr).toContain("aurora inspect-cache: --input is required");
70
+ });
71
+
72
+ it("rejects invalid limit values and unknown options", () => {
73
+ const invalidLimit = runAuroraCli(
74
+ ["inspect-cache", "--input", fixturePath("snapshot.v1.json"), "--limit", "0"],
75
+ { cwd: projectRoot },
76
+ );
77
+ const unknown = runAuroraCli(
78
+ ["inspect-cache", "--input", fixturePath("snapshot.v1.json"), "--unknown"],
79
+ { cwd: projectRoot },
80
+ );
81
+
82
+ expect(invalidLimit.exitCode).toBe(2);
83
+ expect(invalidLimit.stderr).toContain(
84
+ "aurora inspect-cache: --limit must be an integer between 1 and 500",
85
+ );
86
+ expect(unknown.exitCode).toBe(2);
87
+ expect(unknown.stderr).toContain("aurora inspect-cache: unknown option '--unknown'");
88
+ });
89
+
90
+ it("fails for invalid json or unsupported input versions", () => {
91
+ const invalidJsonPath = fixturePath("invalid.json");
92
+ const unsupportedVersionPath = fixturePath("unsupported-version.v2.json");
93
+
94
+ const invalidJson = runAuroraCli(
95
+ ["inspect-cache", "--input", invalidJsonPath],
96
+ { cwd: projectRoot },
97
+ );
98
+ const unsupportedVersion = runAuroraCli(
99
+ ["inspect-cache", "--input", unsupportedVersionPath],
100
+ { cwd: projectRoot },
101
+ );
102
+
103
+ expect(invalidJson.exitCode).toBe(1);
104
+ expect(invalidJson.stderr).toContain(
105
+ `aurora inspect-cache: invalid json input at ${invalidJsonPath}`,
106
+ );
107
+ expect(unsupportedVersion.exitCode).toBe(1);
108
+ expect(unsupportedVersion.stderr).toContain(
109
+ "aurora inspect-cache: unsupported cache snapshot version 2; expected 1",
110
+ );
111
+ });
112
+ });
@@ -0,0 +1,65 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import { describe, expect, it } from "bun:test";
5
+
6
+ import {
7
+ createInlineHintsFromExplainReport,
8
+ type ExplainModuleReportV1,
9
+ } from "../src";
10
+
11
+ function loadExplainFixture(name: string): ExplainModuleReportV1 {
12
+ const raw = readFileSync(join(import.meta.dir, "fixtures/explain", name), "utf8");
13
+ return JSON.parse(raw) as ExplainModuleReportV1;
14
+ }
15
+
16
+ describe("createInlineHintsFromExplainReport", () => {
17
+ it("emits key/tag/invalidation/auth/runtime inline hints with stable ordering", () => {
18
+ const report = loadExplainFixture("module-report.v1.json");
19
+ const source = [
20
+ 'export const runtime = "edge";',
21
+ 'export const auth = "user";',
22
+ "",
23
+ "export const listMessages = defineQuery({});",
24
+ "export const addMessage = defineAction({});",
25
+ ].join("\n");
26
+
27
+ const hints = createInlineHintsFromExplainReport(source, report);
28
+
29
+ expect(hints.length >= 7).toBe(true);
30
+
31
+ const keyHint = hints.find((hint) => hint.kind === "key" && hint.symbol === "listMessages");
32
+ const tagsHint = hints.find((hint) => hint.kind === "tags" && hint.symbol === "listMessages");
33
+ const invalidationHint = hints.find(
34
+ (hint) => hint.kind === "invalidation" && hint.symbol === "addMessage",
35
+ );
36
+ const actionAuthHint = hints.find((hint) => hint.kind === "auth" && hint.symbol === "addMessage");
37
+ const runtimeHint = hints.find((hint) => hint.kind === "runtime" && hint.symbol === "module");
38
+ const moduleAuthHint = hints.find((hint) => hint.kind === "auth" && hint.symbol === "module");
39
+
40
+ expect(keyHint?.label).toContain("key:");
41
+ expect(tagsHint?.label).toContain("tags:");
42
+ expect(invalidationHint?.label).toContain("invalidates:");
43
+ expect(actionAuthHint?.label).toContain("auth: public");
44
+ expect(runtimeHint?.label).toBe("runtime: edge");
45
+ expect(moduleAuthHint?.label).toBe("auth: user");
46
+
47
+ expect(runtimeHint?.position.line).toBe(0);
48
+ expect(moduleAuthHint?.position.line).toBe(1);
49
+
50
+ const lines = hints.map((hint) => hint.position.line);
51
+ const sorted = [...lines].sort((left, right) => left - right);
52
+ expect(lines).toEqual(sorted);
53
+ });
54
+
55
+ it("does not emit query/action hints when symbols are missing from source", () => {
56
+ const report = loadExplainFixture("module-report.v1.json");
57
+ const source = 'export const runtime = "node";';
58
+
59
+ const hints = createInlineHintsFromExplainReport(source, report);
60
+
61
+ expect(hints.some((hint) => hint.symbol === "listMessages")).toBe(false);
62
+ expect(hints.some((hint) => hint.symbol === "addMessage")).toBe(false);
63
+ expect(hints.some((hint) => hint.kind === "runtime")).toBe(true);
64
+ });
65
+ });
@@ -0,0 +1,123 @@
1
+ import { join } from "node:path";
2
+
3
+ import { describe, expect, it } from "bun:test";
4
+
5
+ import { runAuroraCli } from "../src";
6
+
7
+ const projectRoot = join(import.meta.dir, "..");
8
+
9
+ function fixturePath(name: string): string {
10
+ return join("test/fixtures/query-profiler", name);
11
+ }
12
+
13
+ describe("aurora profile-query", () => {
14
+ it("reports healthy query metrics with default thresholds", () => {
15
+ const result = runAuroraCli(
16
+ ["profile-query", "--input", fixturePath("healthy.v1.json")],
17
+ { cwd: projectRoot },
18
+ );
19
+
20
+ expect(result.exitCode).toBe(0);
21
+ expect(result.stdout).toContain("aurora query profiler report");
22
+ expect(result.stdout).toContain("status: ok");
23
+ expect(result.stdout).toContain("cache_hit_ratio: 0.6667");
24
+ expect(result.stdout).toContain("p95_ms: 35.00");
25
+ });
26
+
27
+ it("returns warn status and non-zero exit when thresholds are exceeded", () => {
28
+ const result = runAuroraCli(
29
+ ["profile-query", "--input", fixturePath("warning.v1.json")],
30
+ { cwd: projectRoot },
31
+ );
32
+
33
+ expect(result.exitCode).toBe(1);
34
+ expect(result.stdout).toContain("status: warn");
35
+ expect(result.stdout).toContain("[QUERY_P95_EXCEEDED]");
36
+ expect(result.stdout).toContain("[CACHE_HIT_RATIO_BELOW_MIN]");
37
+ });
38
+
39
+ it("supports json output and custom thresholds", () => {
40
+ const result = runAuroraCli(
41
+ [
42
+ "profile-query",
43
+ "--input",
44
+ fixturePath("healthy.v1.json"),
45
+ "--format",
46
+ "json",
47
+ "--max-p95-ms",
48
+ "40",
49
+ "--min-cache-hit-ratio",
50
+ "0.5",
51
+ "--limit",
52
+ "1",
53
+ ],
54
+ { cwd: projectRoot },
55
+ );
56
+
57
+ expect(result.exitCode).toBe(0);
58
+ const parsed = JSON.parse(result.stdout ?? "{}") as {
59
+ mode?: string;
60
+ status?: string;
61
+ p95Ms?: number;
62
+ cacheHitRatio?: number;
63
+ slowQueries?: Array<{ queryName?: string }>;
64
+ thresholds?: {
65
+ maxP95Ms?: number;
66
+ minCacheHitRatio?: number;
67
+ };
68
+ };
69
+
70
+ expect(parsed.mode).toBe("query-profiler");
71
+ expect(parsed.status).toBe("ok");
72
+ expect(parsed.p95Ms).toBe(35);
73
+ expect((parsed.cacheHitRatio ?? 0).toFixed(4)).toBe("0.6667");
74
+ expect(parsed.thresholds?.maxP95Ms).toBe(40);
75
+ expect(parsed.thresholds?.minCacheHitRatio).toBe(0.5);
76
+ expect(parsed.slowQueries?.length).toBe(1);
77
+ expect(parsed.slowQueries?.[0]?.queryName).toBe("teams.list");
78
+ });
79
+
80
+ it("rejects missing input, invalid limits, and unknown options", () => {
81
+ const missingInput = runAuroraCli(["profile-query"], { cwd: projectRoot });
82
+ const invalidLimit = runAuroraCli(
83
+ ["profile-query", "--input", fixturePath("healthy.v1.json"), "--limit", "0"],
84
+ { cwd: projectRoot },
85
+ );
86
+ const unknown = runAuroraCli(
87
+ ["profile-query", "--input", fixturePath("healthy.v1.json"), "--unknown"],
88
+ { cwd: projectRoot },
89
+ );
90
+
91
+ expect(missingInput.exitCode).toBe(2);
92
+ expect(missingInput.stderr).toContain("aurora profile-query: --input is required");
93
+ expect(invalidLimit.exitCode).toBe(2);
94
+ expect(invalidLimit.stderr).toContain(
95
+ "aurora profile-query: --limit must be an integer between 1 and 200",
96
+ );
97
+ expect(unknown.exitCode).toBe(2);
98
+ expect(unknown.stderr).toContain("aurora profile-query: unknown option '--unknown'");
99
+ });
100
+
101
+ it("fails for invalid json and unsupported schema versions", () => {
102
+ const invalidJsonPath = fixturePath("invalid.json");
103
+ const unsupportedPath = fixturePath("unsupported-version.v2.json");
104
+
105
+ const invalidJson = runAuroraCli(
106
+ ["profile-query", "--input", invalidJsonPath],
107
+ { cwd: projectRoot },
108
+ );
109
+ const unsupported = runAuroraCli(
110
+ ["profile-query", "--input", unsupportedPath],
111
+ { cwd: projectRoot },
112
+ );
113
+
114
+ expect(invalidJson.exitCode).toBe(1);
115
+ expect(invalidJson.stderr).toContain(
116
+ `aurora profile-query: invalid json input at ${invalidJsonPath}`,
117
+ );
118
+ expect(unsupported.exitCode).toBe(1);
119
+ expect(unsupported.stderr).toContain(
120
+ "aurora profile-query: unsupported schemaVersion 2 for query input; expected 1",
121
+ );
122
+ });
123
+ });
@@ -0,0 +1,115 @@
1
+ import { join } from "node:path";
2
+
3
+ import { describe, expect, it } from "bun:test";
4
+
5
+ import { runAuroraCli } from "../src";
6
+
7
+ const projectRoot = join(import.meta.dir, "..");
8
+
9
+ function fixturePath(name: string): string {
10
+ return join("test/fixtures/realtime-monitor", name);
11
+ }
12
+
13
+ describe("aurora monitor-realtime", () => {
14
+ it("reports healthy realtime metrics with default thresholds", () => {
15
+ const result = runAuroraCli(
16
+ ["monitor-realtime", "--input", fixturePath("healthy.v1.json")],
17
+ { cwd: projectRoot },
18
+ );
19
+
20
+ expect(result.exitCode).toBe(0);
21
+ expect(result.stdout).toContain("aurora realtime monitor report");
22
+ expect(result.stdout).toContain("status: ok");
23
+ expect(result.stdout).toContain("drop_ratio: 0.0100");
24
+ expect(result.stdout).toContain("lag_p95_ms: 140");
25
+ });
26
+
27
+ it("returns warn status and non-zero exit when thresholds are exceeded", () => {
28
+ const result = runAuroraCli(
29
+ ["monitor-realtime", "--input", fixturePath("warning.v1.json")],
30
+ { cwd: projectRoot },
31
+ );
32
+
33
+ expect(result.exitCode).toBe(1);
34
+ expect(result.stdout).toContain("status: warn");
35
+ expect(result.stdout).toContain("[DROP_RATIO_EXCEEDED]");
36
+ expect(result.stdout).toContain("[LAG_P95_EXCEEDED]");
37
+ });
38
+
39
+ it("supports json output and custom thresholds", () => {
40
+ const result = runAuroraCli(
41
+ [
42
+ "monitor-realtime",
43
+ "--input",
44
+ fixturePath("healthy.v1.json"),
45
+ "--format",
46
+ "json",
47
+ "--max-drop-ratio",
48
+ "0.02",
49
+ "--max-lag-p95-ms",
50
+ "180",
51
+ "--min-delivered-rps",
52
+ "10",
53
+ ],
54
+ { cwd: projectRoot },
55
+ );
56
+
57
+ expect(result.exitCode).toBe(0);
58
+ const parsed = JSON.parse(result.stdout ?? "{}") as {
59
+ mode?: string;
60
+ status?: string;
61
+ dropRatio?: number;
62
+ deliveredRps?: number;
63
+ thresholds?: {
64
+ minDeliveredRps?: number;
65
+ };
66
+ issues?: unknown[];
67
+ };
68
+
69
+ expect(parsed.mode).toBe("realtime-monitor");
70
+ expect(parsed.status).toBe("ok");
71
+ expect(parsed.dropRatio).toBe(0.01);
72
+ expect(parsed.deliveredRps).toBe(19.8);
73
+ expect(parsed.thresholds?.minDeliveredRps).toBe(10);
74
+ expect(parsed.issues?.length).toBe(0);
75
+ });
76
+
77
+ it("rejects missing input and unknown options", () => {
78
+ const missingInput = runAuroraCli(["monitor-realtime"], {
79
+ cwd: projectRoot,
80
+ });
81
+ const unknown = runAuroraCli(
82
+ ["monitor-realtime", "--input", fixturePath("healthy.v1.json"), "--unknown"],
83
+ { cwd: projectRoot },
84
+ );
85
+
86
+ expect(missingInput.exitCode).toBe(2);
87
+ expect(missingInput.stderr).toContain(
88
+ "aurora monitor-realtime: --input is required",
89
+ );
90
+ expect(unknown.exitCode).toBe(2);
91
+ expect(unknown.stderr).toContain(
92
+ "aurora monitor-realtime: unknown option '--unknown'",
93
+ );
94
+ });
95
+
96
+ it("fails for invalid json and unsupported schema versions", () => {
97
+ const invalidJson = runAuroraCli(
98
+ ["monitor-realtime", "--input", fixturePath("invalid.json")],
99
+ { cwd: projectRoot },
100
+ );
101
+ const unsupported = runAuroraCli(
102
+ ["monitor-realtime", "--input", fixturePath("unsupported-version.v2.json")],
103
+ { cwd: projectRoot },
104
+ );
105
+
106
+ expect(invalidJson.exitCode).toBe(1);
107
+ expect(invalidJson.stderr).toContain(
108
+ `aurora monitor-realtime: invalid json input at ${fixturePath("invalid.json")}`,
109
+ );
110
+ expect(unsupported.exitCode).toBe(1);
111
+ expect(unsupported.stderr).toContain(
112
+ "aurora monitor-realtime: unsupported schemaVersion 2 for realtime input; expected 1",
113
+ );
114
+ });
115
+ });
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from "bun:test";
2
+
3
+ import { commandRegistry, findCommand } from "../src";
4
+
5
+ describe("command registry", () => {
6
+ it("contains the baseline command set for bootstrap", () => {
7
+ const names = new Set(commandRegistry.map((command) => command.name));
8
+ const required = [
9
+ "create",
10
+ "init",
11
+ "dev",
12
+ "devtools",
13
+ "build",
14
+ "start",
15
+ "analyze",
16
+ "ai",
17
+ "doctor",
18
+ "explain",
19
+ "inspect-cache",
20
+ "monitor-realtime",
21
+ "profile-query",
22
+ "test",
23
+ "create-feature",
24
+ "create-route",
25
+ ];
26
+
27
+ for (const name of required) {
28
+ expect(names.has(name)).toBe(true);
29
+ }
30
+ });
31
+
32
+ it("registers unique command names", () => {
33
+ const names = commandRegistry.map((command) => command.name);
34
+ expect(new Set(names).size).toBe(names.length);
35
+ });
36
+
37
+ it("findCommand resolves registered commands and rejects unknown commands", () => {
38
+ expect(findCommand("dev")?.name).toBe("dev");
39
+ expect(findCommand("missing")).toBe(undefined);
40
+ });
41
+ });
@@ -0,0 +1,23 @@
1
+ import { describe, expect, it } from "bun:test";
2
+
3
+ import { runAuroraCli } from "../src";
4
+
5
+ describe("aurora start", () => {
6
+ const cwd = "/tmp/aurora-start";
7
+
8
+ it("prints production runtime bootstrap output", () => {
9
+ const result = runAuroraCli(["start"], { cwd });
10
+
11
+ expect(result.exitCode).toBe(0);
12
+ expect(result.stdout).toContain("aurora start bootstrap");
13
+ expect(result.stdout).toContain("runtime_bundle: /tmp/aurora-start/.aurora/build/node/server.mjs");
14
+ expect(result.stdout).toContain("url: http://localhost:3000");
15
+ });
16
+
17
+ it("returns an error for unknown options", () => {
18
+ const result = runAuroraCli(["start", "--port", "4310"], { cwd });
19
+
20
+ expect(result.exitCode).toBe(2);
21
+ expect(result.stderr).toContain("aurora start: unknown option '--port'");
22
+ });
23
+ });
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { mkdirSync } from "node:fs";
3
+
4
+ import { runAuroraCli } from "../src";
5
+
6
+ let tempCounter = 0;
7
+
8
+ function uniqueTempPath(suffix: string): string {
9
+ tempCounter += 1;
10
+ return `/tmp/aurora-cli-test-command-${suffix}-${Date.now()}-${tempCounter}`;
11
+ }
12
+
13
+ describe("aurora test", () => {
14
+ it("runs e2e matrix wrapper for all default template profiles", () => {
15
+ const cwd = uniqueTempPath("all");
16
+ mkdirSync(cwd, { recursive: true });
17
+
18
+ const result = runAuroraCli(["test"], { cwd });
19
+
20
+ expect(result.exitCode).toBe(0);
21
+ expect(result.stdout).toContain("aurora test integration runner");
22
+ expect(result.stdout).toContain("projects_total: 4");
23
+ expect(result.stdout).toContain("projects_failed: 0");
24
+ expect(result.stdout).toContain("basic (basic): PASS");
25
+ expect(result.stdout).toContain("dashboard (dashboard): PASS");
26
+ });
27
+
28
+ it("supports template filter and json report output", () => {
29
+ const cwd = uniqueTempPath("json");
30
+ mkdirSync(cwd, { recursive: true });
31
+
32
+ const result = runAuroraCli(["test", "--template", "blog", "--format", "json"], {
33
+ cwd,
34
+ });
35
+
36
+ expect(result.exitCode).toBe(0);
37
+ const report = JSON.parse(result.stdout ?? "{}") as {
38
+ mode?: string;
39
+ templateFilter?: string;
40
+ projectsTotal?: number;
41
+ projectsFailed?: number;
42
+ results?: Array<{ id: string; passed: boolean }>;
43
+ };
44
+
45
+ expect(report.mode).toBe("test");
46
+ expect(report.templateFilter).toBe("blog");
47
+ expect(report.projectsTotal).toBe(1);
48
+ expect(report.projectsFailed).toBe(0);
49
+ expect(report.results?.[0]?.id).toBe("blog");
50
+ expect(report.results?.[0]?.passed).toBe(true);
51
+ });
52
+
53
+ it("returns parse errors for invalid template and unknown options", () => {
54
+ const cwd = uniqueTempPath("invalid");
55
+ mkdirSync(cwd, { recursive: true });
56
+
57
+ const invalidTemplate = runAuroraCli(["test", "--template", "mobile"], { cwd });
58
+ expect(invalidTemplate.exitCode).toBe(2);
59
+ expect(invalidTemplate.stderr).toContain("invalid template 'mobile'");
60
+
61
+ const unknownOption = runAuroraCli(["test", "--suite", "matrix"], { cwd });
62
+ expect(unknownOption.exitCode).toBe(2);
63
+ expect(unknownOption.stderr).toContain("unknown option '--suite'");
64
+ });
65
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "strict": true,
7
+ "noImplicitThis": true,
8
+ "declaration": true,
9
+ "isolatedModules": true,
10
+ "verbatimModuleSyntax": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": [
14
+ "src/**/*.ts",
15
+ "src/**/*.d.ts",
16
+ "test/**/*.ts",
17
+ "test/**/*.d.ts"
18
+ ]
19
+ }