create-astrale-domain 0.3.0-beta.4 → 0.3.0-beta.6

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/index.js CHANGED
@@ -943,19 +943,7 @@ async function materializeGitignores(dir, frontend) {
943
943
  throw new Error(`Template is missing packaged Git ignore file ${packagedPath}.`);
944
944
  }
945
945
  }
946
- if (frontend === "react") {
947
- const path = join(dir, ".gitignore");
948
- const current = await readFile(path, "utf-8");
949
- await writeFile(
950
- path,
951
- `${current.trimEnd()}
952
-
953
- # SDK-managed React bootstrap (regenerated before every frontend build)
954
- /views/app/index.html
955
- /views/app/astrale.generated.tsx
956
- `
957
- );
958
- }
946
+ void frontend;
959
947
  }
960
948
  async function materializeFrontend(opts, template) {
961
949
  const variant = join(template, ".variants", opts.frontend);
@@ -965,21 +953,31 @@ async function materializeFrontend(opts, template) {
965
953
  const pkg = JSON.parse(await readFile(path, "utf-8"));
966
954
  pkg.dependencies ??= {};
967
955
  pkg.devDependencies ??= {};
956
+ pkg.scripts ??= {};
968
957
  if (opts.frontend === "react") {
969
958
  Object.assign(pkg.dependencies, {
970
959
  "@astrale-os/shell": ">=0.3.8-beta.2 <1.0.0",
971
960
  "@astrale-os/shell-react": ">=0.2.10-beta.2 <1.0.0",
961
+ "@tanstack/react-router": "~1.131.0",
972
962
  react: "^19.2.0",
973
963
  "react-dom": "^19.2.0"
974
964
  });
975
965
  Object.assign(pkg.devDependencies, {
966
+ "@tailwindcss/vite": "^4.0.6",
967
+ "@tanstack/router-plugin": "~1.131.0",
976
968
  "@types/react": "^19.2.0",
977
969
  "@types/react-dom": "^19.2.0",
970
+ "@vitejs/plugin-react": "^5.0.4",
971
+ tailwindcss: "^4.0.6",
978
972
  vite: "^7.1.7"
979
973
  });
980
974
  } else if (opts.frontend === "custom") {
981
975
  pkg.devDependencies.vite = "^7.1.7";
982
976
  }
977
+ if (opts.frontend !== "none") {
978
+ pkg.scripts["frontend:dev"] = "vite";
979
+ pkg.scripts["frontend:build"] = "vite build";
980
+ }
983
981
  pkg.dependencies = sorted(pkg.dependencies);
984
982
  pkg.devDependencies = sorted(pkg.devDependencies);
985
983
  await writeFile(path, JSON.stringify(pkg, null, 2) + "\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-astrale-domain",
3
- "version": "0.3.0-beta.4",
3
+ "version": "0.3.0-beta.6",
4
4
  "description": "Scaffold a standalone Astrale domain — npm create astrale-domain",
5
5
  "keywords": [
6
6
  "astrale",
@@ -22,8 +22,8 @@
22
22
  "type": "module",
23
23
  "dependencies": {
24
24
  "@clack/prompts": "^0.11.0",
25
- "@astrale-os/adapter-astrale": "^0.5.0-beta.4",
26
- "@astrale-os/adapter-cloudflare": "^0.5.0-beta.11"
25
+ "@astrale-os/adapter-astrale": "^0.5.0-beta.6",
26
+ "@astrale-os/adapter-cloudflare": "^0.5.0-beta.13"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@astrale-os/ox": ">=0.1.0 <1.0.0",
@@ -34,7 +34,7 @@
34
34
  "oxlint": "latest",
35
35
  "typescript": "~6.0.1-rc",
36
36
  "vitest": "^3.0.0",
37
- "@astrale-os/sdk": "^0.5.0-beta.8"
37
+ "@astrale-os/sdk": "^0.5.0-beta.10"
38
38
  },
39
39
  "engines": {
40
40
  "node": ">=22"
@@ -1,7 +1,7 @@
1
1
  # Astrale Domain
2
2
 
3
3
  This project uses the framework-neutral frontend escape hatch. `views/routes.ts` binds declared
4
- Views to a `frontendArtifact`; `views/app/` is an ordinary Vite root you can replace with any
4
+ Views to a `frontendArtifact`; `vite.config.ts` owns the ordinary Vite root you can replace with any
5
5
  framework; `ui/` owns presentation assets. The starter route uses `handshake: 'none'`, so it mounts
6
6
  as a plain hosted app. Change that route to `handshake: 'shell'` only after your browser entrypoint
7
7
  boots the Shell protocol.
@@ -1,13 +1,12 @@
1
- import { frontendArtifact, frontendRoute, viteFrontend } from '@astrale-os/sdk/view'
1
+ import { frontendArtifact, viteFrontend } from '@astrale-os/sdk/view'
2
2
 
3
3
  import { schema } from '#schema'
4
4
 
5
5
  /** Framework-neutral escape hatch: swap Vite or the browser implementation without changing Views. */
6
6
  export const frontend = frontendArtifact({
7
7
  schema,
8
- source: viteFrontend({ root: './views/app' }),
8
+ source: viteFrontend(),
9
9
  routes: {
10
- application: frontendRoute({ path: '/ui/application', handshake: 'none' }),
10
+ application: { handshake: 'none' },
11
11
  },
12
- entrypoint: 'application',
13
12
  })
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vite'
2
+
3
+ export default defineConfig({
4
+ root: 'views/app',
5
+ build: {
6
+ outDir: '../../dist/frontend',
7
+ emptyOutDir: true,
8
+ },
9
+ })
@@ -1,23 +1,23 @@
1
1
  # Astrale Domain
2
2
 
3
- This project uses the managed React frontend path. `views/routes.ts` is Worker-safe metadata;
4
- `views/application/application.view.tsx` owns Domain integration; `ui/` owns pure presentation.
5
- The adapter generates the shell boot module under `views/app/`, builds it, publishes the declared
6
- route, and serves the immutable static files beside the callable Worker.
3
+ This project is an ordinary Vite React application. `views/routes.ts` is the small Worker-safe
4
+ delivery artifact; `frontend/` owns TanStack Router and browser composition; `ui/` owns reusable
5
+ presentation. `<Astrale>` supplies the existing Shell session, graph context, error/loading
6
+ boundaries, hooks, and View stage without taking over browser history.
7
7
 
8
8
  ```text
9
9
  schema/ public Domain contract, including View declarations
10
10
  implementation.ts schema, callable handlers, and frontend composition
11
- views/routes.ts typed route and browser-module coordinates
12
- views/application/ Domain-aware React View
13
- views/app/ managed browser build root
11
+ views/routes.ts schema-bound delivery metadata
12
+ frontend/ Vite, file-based TanStack Router, and Tailwind entrypoint
14
13
  ui/ styles and pure presentation components
15
14
  tests/ cross-layer executable journeys
16
15
  ```
17
16
 
18
- Run `pnpm dev` for a local Worker, `pnpm build` to pressure-test Worker and frontend output,
17
+ Run `pnpm dev` for one Worker-facing URL with Vite HMR, `pnpm build` to qualify Worker and frontend output,
19
18
  and `pnpm prod` to deploy through the selected adapter. Add semantic `rules/`, `queries/`,
20
19
  `mutations/`, and `functions/` modules only when the Domain gains those responsibilities.
21
20
 
22
21
  Domain projects intentionally own no `.spec` trees. Import authoring contracts through semantic
23
- `@astrale-os/sdk/*` subpaths; never import Kernel Core or DSL directly.
22
+ `@astrale-os/sdk/*` subpaths; never import Kernel Core or DSL directly. Routing remains a normal
23
+ TanStack Router concern; Astrale hooks remain normal React hooks inside route components.
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Astrale Domain</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,18 @@
1
+ import { Astrale } from '@astrale-os/shell-react'
2
+ import { RouterProvider } from '@tanstack/react-router'
3
+ import { StrictMode } from 'react'
4
+ import { createRoot } from 'react-dom/client'
5
+
6
+ import { router } from './router.js'
7
+ import './styles.css'
8
+
9
+ const root = document.querySelector('#root')
10
+ if (root === null) throw new Error('React root #root is missing.')
11
+
12
+ createRoot(root).render(
13
+ <StrictMode>
14
+ <Astrale>
15
+ <RouterProvider router={router} />
16
+ </Astrale>
17
+ </StrictMode>,
18
+ )
@@ -0,0 +1,77 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as AboutRouteImport } from './routes/about'
13
+ import { Route as IndexRouteImport } from './routes/index'
14
+
15
+ const AboutRoute = AboutRouteImport.update({
16
+ id: '/about',
17
+ path: '/about',
18
+ getParentRoute: () => rootRouteImport,
19
+ } as any)
20
+ const IndexRoute = IndexRouteImport.update({
21
+ id: '/',
22
+ path: '/',
23
+ getParentRoute: () => rootRouteImport,
24
+ } as any)
25
+
26
+ export interface FileRoutesByFullPath {
27
+ '/': typeof IndexRoute
28
+ '/about': typeof AboutRoute
29
+ }
30
+ export interface FileRoutesByTo {
31
+ '/': typeof IndexRoute
32
+ '/about': typeof AboutRoute
33
+ }
34
+ export interface FileRoutesById {
35
+ __root__: typeof rootRouteImport
36
+ '/': typeof IndexRoute
37
+ '/about': typeof AboutRoute
38
+ }
39
+ export interface FileRouteTypes {
40
+ fileRoutesByFullPath: FileRoutesByFullPath
41
+ fullPaths: '/' | '/about'
42
+ fileRoutesByTo: FileRoutesByTo
43
+ to: '/' | '/about'
44
+ id: '__root__' | '/' | '/about'
45
+ fileRoutesById: FileRoutesById
46
+ }
47
+ export interface RootRouteChildren {
48
+ IndexRoute: typeof IndexRoute
49
+ AboutRoute: typeof AboutRoute
50
+ }
51
+
52
+ declare module '@tanstack/react-router' {
53
+ interface FileRoutesByPath {
54
+ '/about': {
55
+ id: '/about'
56
+ path: '/about'
57
+ fullPath: '/about'
58
+ preLoaderRoute: typeof AboutRouteImport
59
+ parentRoute: typeof rootRouteImport
60
+ }
61
+ '/': {
62
+ id: '/'
63
+ path: '/'
64
+ fullPath: '/'
65
+ preLoaderRoute: typeof IndexRouteImport
66
+ parentRoute: typeof rootRouteImport
67
+ }
68
+ }
69
+ }
70
+
71
+ const rootRouteChildren: RootRouteChildren = {
72
+ IndexRoute: IndexRoute,
73
+ AboutRoute: AboutRoute,
74
+ }
75
+ export const routeTree = rootRouteImport
76
+ ._addFileChildren(rootRouteChildren)
77
+ ._addFileTypes<FileRouteTypes>()
@@ -0,0 +1,11 @@
1
+ import { createRouter } from '@tanstack/react-router'
2
+
3
+ import { routeTree } from './routeTree.gen.js'
4
+
5
+ export const router = createRouter({ routeTree, basepath: '/application' })
6
+
7
+ declare module '@tanstack/react-router' {
8
+ interface Register {
9
+ router: typeof router
10
+ }
11
+ }
@@ -0,0 +1,30 @@
1
+ import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
2
+
3
+ export const Route = createRootRoute({ component: ApplicationLayout })
4
+
5
+ function ApplicationLayout() {
6
+ return (
7
+ <div className="min-h-screen bg-stone-950 text-stone-100">
8
+ <header className="mx-auto flex max-w-5xl items-center justify-between border-b border-white/10 px-6 py-5">
9
+ <Link to="/" className="font-medium tracking-tight">
10
+ Astrale Domain
11
+ </Link>
12
+ <nav className="flex gap-1 text-sm text-stone-400" aria-label="Application">
13
+ <Link
14
+ to="/"
15
+ className="rounded-full px-3 py-1.5 [&.active]:bg-white/10 [&.active]:text-white"
16
+ >
17
+ Overview
18
+ </Link>
19
+ <Link
20
+ to="/about"
21
+ className="rounded-full px-3 py-1.5 [&.active]:bg-white/10 [&.active]:text-white"
22
+ >
23
+ About
24
+ </Link>
25
+ </nav>
26
+ </header>
27
+ <Outlet />
28
+ </div>
29
+ )
30
+ }
@@ -0,0 +1,16 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+
3
+ export const Route = createFileRoute('/about')({ component: About })
4
+
5
+ function About() {
6
+ return (
7
+ <main className="mx-auto grid max-w-5xl gap-4 px-6 py-16">
8
+ <p className="font-mono text-xs uppercase tracking-[0.2em] text-amber-300">Internal route</p>
9
+ <h1 className="text-4xl font-semibold tracking-tight">TanStack Router owns this history.</h1>
10
+ <p className="max-w-2xl leading-7 text-stone-400">
11
+ Add route files here, compose any React stack you want, and use Astrale hooks only where the
12
+ application needs Shell, graph, target, or host capabilities.
13
+ </p>
14
+ </main>
15
+ )
16
+ }
@@ -0,0 +1,19 @@
1
+ import { useDomain, useTargetPath } from '@astrale-os/shell-react'
2
+ import { createFileRoute } from '@tanstack/react-router'
3
+
4
+ import { schema } from '#schema'
5
+ import { ApplicationScreen } from '#ui/application'
6
+
7
+ export const Route = createFileRoute('/')({ component: Overview })
8
+
9
+ function Overview() {
10
+ const domain = useDomain(schema)
11
+ const target = useTargetPath()
12
+ return (
13
+ <ApplicationScreen
14
+ eyebrow={schema.origin}
15
+ title="Your application, your router."
16
+ detail={`Shell connected to ${domain.application.name}; target ${target?.raw ?? 'is the Domain root'}.`}
17
+ />
18
+ )
19
+ }
@@ -0,0 +1,19 @@
1
+ @import 'tailwindcss';
2
+
3
+ :root {
4
+ color: #f5f5f4;
5
+ background: #12120f;
6
+ font-family: Inter, ui-sans-serif, system-ui, sans-serif;
7
+ font-synthesis: none;
8
+ }
9
+
10
+ body {
11
+ min-width: 20rem;
12
+ min-height: 100vh;
13
+ margin: 0;
14
+ }
15
+
16
+ button,
17
+ a {
18
+ -webkit-tap-highlight-color: transparent;
19
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -1,5 +1,3 @@
1
- import './styles.css'
2
-
3
1
  export interface ApplicationScreenProps {
4
2
  readonly eyebrow: string
5
3
  readonly title: string
@@ -9,10 +7,12 @@ export interface ApplicationScreenProps {
9
7
  /** Pure presentation: no graph, routing, credentials, or Domain imports. */
10
8
  export function ApplicationScreen({ eyebrow, title, detail }: ApplicationScreenProps) {
11
9
  return (
12
- <main className="application-shell">
13
- <p className="application-eyebrow">{eyebrow}</p>
14
- <h1>{title}</h1>
15
- <p>{detail}</p>
10
+ <main className="mx-auto grid min-h-[70vh] max-w-5xl content-center gap-6 px-6 py-16">
11
+ <p className="font-mono text-xs uppercase tracking-[0.2em] text-amber-300">{eyebrow}</p>
12
+ <h1 className="max-w-4xl text-5xl font-semibold tracking-[-0.055em] text-stone-50 sm:text-7xl">
13
+ {title}
14
+ </h1>
15
+ <p className="max-w-2xl text-lg leading-8 text-stone-400">{detail}</p>
16
16
  </main>
17
17
  )
18
18
  }
@@ -1,16 +1,9 @@
1
- import { reactFrontend, reactRoute } from '@astrale-os/sdk/react'
1
+ import { frontendArtifact, viteFrontend } from '@astrale-os/sdk/view'
2
2
 
3
3
  import { schema } from '#schema'
4
4
 
5
- /** Worker-safe route metadata. Browser modules are coordinates, never Worker imports. */
6
- export const frontend = reactFrontend({
5
+ /** The complete deploy contract; Vite and the browser application stay author-owned. */
6
+ export const frontend = frontendArtifact({
7
7
  schema,
8
- schemaModule: { module: './schema/index.ts', export: 'schema' },
9
- routes: {
10
- application: reactRoute({
11
- path: '/ui/application',
12
- component: { module: './views/application/application.view.tsx' },
13
- }),
14
- },
15
- entrypoint: 'application',
8
+ source: viteFrontend(),
16
9
  })
@@ -0,0 +1,22 @@
1
+ import tailwindcss from '@tailwindcss/vite'
2
+ import { tanstackRouter } from '@tanstack/router-plugin/vite'
3
+ import react from '@vitejs/plugin-react'
4
+ import { defineConfig } from 'vite'
5
+
6
+ export default defineConfig({
7
+ root: 'frontend',
8
+ plugins: [
9
+ tanstackRouter({
10
+ target: 'react',
11
+ autoCodeSplitting: true,
12
+ routesDirectory: './frontend/src/routes',
13
+ generatedRouteTree: './frontend/src/routeTree.gen.ts',
14
+ }),
15
+ react(),
16
+ tailwindcss(),
17
+ ],
18
+ build: {
19
+ outDir: '../dist/frontend',
20
+ emptyOutDir: true,
21
+ },
22
+ })
@@ -12,9 +12,7 @@ allowBuilds:
12
12
  '@astrale-os/kernel-client': false
13
13
  '@astrale-os/kernel-core': false
14
14
  '@astrale-os/kernel-dsl': false
15
- '@astrale-os/kernel-ports': false
16
15
  '@astrale-os/kernel-protocol': false
17
- '@astrale-os/kernel-runtime': false
18
16
  '@astrale-os/kernel-server': false
19
17
  '@astrale-os/sdk': false
20
18
  '@astrale-os/shell': false
@@ -31,9 +29,7 @@ ignoredBuiltDependencies:
31
29
  - '@astrale-os/kernel-client'
32
30
  - '@astrale-os/kernel-core'
33
31
  - '@astrale-os/kernel-dsl'
34
- - '@astrale-os/kernel-ports'
35
32
  - '@astrale-os/kernel-protocol'
36
- - '@astrale-os/kernel-runtime'
37
33
  - '@astrale-os/kernel-server'
38
34
  - '@astrale-os/sdk'
39
35
  - '@astrale-os/shell'
@@ -57,6 +57,7 @@
57
57
  "capabilities",
58
58
  "functions",
59
59
  "integrations",
60
+ "frontend",
60
61
  "views",
61
62
  "ui",
62
63
  "utils",
@@ -64,7 +65,8 @@
64
65
  "tests",
65
66
  "implementation.ts",
66
67
  "index.ts",
67
- "astrale.config.ts"
68
+ "astrale.config.ts",
69
+ "vite.config.ts"
68
70
  ],
69
71
  "exclude": ["node_modules", ".dist", ".wrangler", "**/__tests__/**"]
70
72
  }
@@ -1,34 +0,0 @@
1
- :root {
2
- color: #f5f3ed;
3
- background: #171714;
4
- font-family: Inter, ui-sans-serif, system-ui, sans-serif;
5
- }
6
-
7
- body {
8
- margin: 0;
9
- }
10
-
11
- .application-shell {
12
- box-sizing: border-box;
13
- display: grid;
14
- min-height: 100vh;
15
- align-content: center;
16
- gap: 1rem;
17
- max-width: 64rem;
18
- padding: 4rem;
19
- margin: 0 auto;
20
- }
21
-
22
- .application-shell h1 {
23
- margin: 0;
24
- font-size: clamp(3rem, 9vw, 7rem);
25
- line-height: 0.92;
26
- letter-spacing: -0.06em;
27
- }
28
-
29
- .application-eyebrow {
30
- color: #e3b866;
31
- font-family: ui-monospace, monospace;
32
- text-transform: uppercase;
33
- letter-spacing: 0.12em;
34
- }
@@ -1 +0,0 @@
1
- declare module '*.css' {}
@@ -1,4 +0,0 @@
1
- # Managed React entrypoint
2
-
3
- The adapter generates `index.html` and `astrale.generated.tsx` here from `views/routes.ts` before
4
- Vite builds the frontend. Keep browser build configuration here only when the application needs it.
@@ -1,19 +0,0 @@
1
- import type { ReactViewProps } from '@astrale-os/sdk/react'
2
-
3
- import { Domain } from '@astrale-os/sdk/domain'
4
-
5
- import { schema } from '#schema'
6
- import { ApplicationScreen } from '#ui/application'
7
-
8
- const application = Domain.fromSchema(schema).application
9
-
10
- /** Domain-aware View integration; Queries, Rules, and named actions belong here. */
11
- export default function ApplicationView({ target, route }: ReactViewProps<typeof application>) {
12
- return (
13
- <ApplicationScreen
14
- eyebrow={target.origin}
15
- title="Ready to build."
16
- detail={`Mounted as ${route.name} at ${route.href}`}
17
- />
18
- )
19
- }