@construct-space/cli 1.0.6 → 1.1.0

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Space Actions — exposed to the AI agent via space_run_action
3
+ *
4
+ * Define actions here and they'll be automatically available as agent tools.
5
+ * The agent calls: space_run_action(action: "action_id", payload: {...})
6
+ */
7
+
8
+ // --- Graph SDK (data layer) ---
9
+ // Uncomment after running `construct graph init` and defining models:
10
+ //
11
+ // import { useGraph } from '@construct-space/graph'
12
+ // const graph = useGraph()
13
+ //
14
+ // Example action using Graph:
15
+ // fetchItems: {
16
+ // description: 'Fetch items from the graph',
17
+ // params: {
18
+ // limit: { type: 'number', description: 'Max items to return', required: false },
19
+ // },
20
+ // run: async (p: any) => {
21
+ // const items = await graph.query('Item').limit(p.limit ?? 10).exec()
22
+ // return { items }
23
+ // },
24
+ // },
25
+
26
+ export const actions = {
27
+ // Example action:
28
+ // hello: {
29
+ // description: 'Say hello',
30
+ // params: {
31
+ // name: { type: 'string', description: 'Name to greet', required: true },
32
+ // },
33
+ // run: (p: any) => ({ message: `Hello ${p.name}!` }),
34
+ // },
35
+ }
@@ -4,14 +4,20 @@ name: {{.DisplayName}}
4
4
  category: space
5
5
  description: AI agent for the {{.DisplayName}} space
6
6
  maxIterations: 15
7
+ tools: []
7
8
  canInvokeAgents: []
8
9
  ---
9
10
 
10
- You are Construct's {{.DisplayName}} agent. You help users work effectively within the {{.DisplayName}} space.
11
+ You are Construct's {{.DisplayName}} agent. You help users work within the {{.DisplayName}} space.
12
+
13
+ ## Context
14
+
15
+ Use space_list_actions to discover available actions for this space.
16
+ Use space_run_action to execute actions.
17
+ Do NOT call get_project_context — you work with space content, not project files.
11
18
 
12
19
  ## Behavior
13
20
 
14
- - Use get_project_context to understand the current project before acting
15
- - Read files before modifying them
16
- - Focus on tasks relevant to this space
21
+ - Start by listing available actions to understand what you can do
17
22
  - Be concise and action-oriented
23
+ - Focus on tasks relevant to this space
@@ -0,0 +1,14 @@
1
+ // Space entry — exports pages, widgets, and actions for the host loader.
2
+ // `construct dev` regenerates this from space.manifest.json on changes.
3
+ import IndexPage from './pages/index.vue'
4
+ import { actions } from './actions'
5
+
6
+ const spaceExport = {
7
+ pages: {
8
+ '': IndexPage,
9
+ },
10
+ widgets: {},
11
+ actions,
12
+ }
13
+
14
+ export default spaceExport
@@ -0,0 +1,16 @@
1
+ // Space entry — exports pages, widgets, and actions for the host loader.
2
+ // `construct dev` regenerates this from space.manifest.json on changes.
3
+ import IndexPage from './pages/index.vue'
4
+ import SettingsPage from './pages/settings.vue'
5
+ import { actions } from './actions'
6
+
7
+ const spaceExport = {
8
+ pages: {
9
+ '': IndexPage,
10
+ 'settings': SettingsPage,
11
+ },
12
+ widgets: {},
13
+ actions,
14
+ }
15
+
16
+ export default spaceExport
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * {{.DisplayName}} — Settings page
4
+ */
5
+ import { ref } from 'vue'
6
+
7
+ const autoSave = ref(true)
8
+ const theme = ref<'system' | 'light' | 'dark'>('system')
9
+ </script>
10
+
11
+ <template>
12
+ <div class="h-full overflow-auto p-6">
13
+ <h1 class="text-xl font-bold text-[var(--app-foreground)] mb-6">Settings</h1>
14
+
15
+ <div class="space-y-4 max-w-md">
16
+ <label class="flex items-center justify-between">
17
+ <span class="text-sm text-[var(--app-foreground)]">Auto-save</span>
18
+ <input v-model="autoSave" type="checkbox" class="rounded" />
19
+ </label>
20
+
21
+ <label class="block">
22
+ <span class="text-sm text-[var(--app-foreground)] block mb-1">Theme</span>
23
+ <select v-model="theme" class="w-full rounded border border-[var(--app-border)] bg-[var(--app-background)] px-3 py-1.5 text-sm">
24
+ <option value="system">System</option>
25
+ <option value="light">Light</option>
26
+ <option value="dark">Dark</option>
27
+ </select>
28
+ </label>
29
+ </div>
30
+ </div>
31
+ </template>
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: {{.ID}}-data
3
+ name: {{.DisplayName}} Data Management
4
+ description: Skill for managing {{.DisplayName}} data and content
5
+ trigger: {{.ID}} data|content|manage
6
+ category: space
7
+ tools: [read_file, list_dir, glob, grep, write_file]
8
+ ---
9
+
10
+ # {{.DisplayName}} Data Management Skill
11
+
12
+ This skill handles data operations for the {{.DisplayName}} space.
13
+
14
+ ## Instructions
15
+ - Help users create, read, update, and delete content
16
+ - Validate data before writing
17
+ - Use the space actions API when available
18
+ - Prefer batch operations for bulk changes
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: {{.ID}}-ui
3
+ name: {{.DisplayName}} UI Customization
4
+ description: Skill for customizing the {{.DisplayName}} user interface
5
+ trigger: {{.ID}} ui|layout|design|style
6
+ category: space
7
+ tools: [read_file, write_file, glob]
8
+ ---
9
+
10
+ # {{.DisplayName}} UI Customization Skill
11
+
12
+ This skill helps customize the {{.DisplayName}} space interface.
13
+
14
+ ## Instructions
15
+ - Help users adjust layout and styling
16
+ - Use Construct CSS variables (--app-foreground, --app-background, --app-accent, etc.)
17
+ - Follow the host design system conventions
18
+ - Suggest accessible color combinations
@@ -0,0 +1,60 @@
1
+ {
2
+ "id": "{{.ID}}",
3
+ "name": "{{.DisplayName}}",
4
+ "version": "0.1.0",
5
+ "description": "{{.DisplayName}} space for Construct",
6
+ "author": {
7
+ "name": "Your Name"
8
+ },
9
+ "icon": "i-lucide-box",
10
+ "scope": "both",
11
+ "minConstructVersion": "0.7.0",
12
+ "navigation": {
13
+ "label": "{{.DisplayName}}",
14
+ "icon": "i-lucide-box",
15
+ "to": "{{.ID}}",
16
+ "order": 100
17
+ },
18
+ "pages": [
19
+ {
20
+ "path": "",
21
+ "label": "Home",
22
+ "icon": "i-lucide-home",
23
+ "default": true
24
+ },
25
+ {
26
+ "path": "settings",
27
+ "label": "Settings",
28
+ "icon": "i-lucide-settings"
29
+ }
30
+ ],
31
+ "toolbar": [
32
+ {
33
+ "id": "{{.ID}}-new",
34
+ "icon": "i-lucide-plus",
35
+ "label": "New {{.DisplayName}}",
36
+ "action": "create{{.DisplayNameNoSpace}}"
37
+ }
38
+ ],
39
+ "keywords": ["{{.ID}}"],
40
+ "agent": "agent/config.md",
41
+ "skills": [
42
+ "agent/skills/default.md",
43
+ "agent/skills/data.md",
44
+ "agent/skills/ui.md"
45
+ ],
46
+ "actions": "src/actions.ts",
47
+ "widgets": [
48
+ {
49
+ "id": "summary",
50
+ "name": "{{.DisplayName}} Summary",
51
+ "description": "Quick summary widget for {{.DisplayName}}",
52
+ "icon": "i-lucide-box",
53
+ "defaultSize": "4x1",
54
+ "sizes": {
55
+ "2x1": "widgets/summary/2x1.vue",
56
+ "4x1": "widgets/summary/4x1.vue"
57
+ }
58
+ }
59
+ ]
60
+ }
@@ -1,14 +1,20 @@
1
1
  <script setup lang="ts">
2
2
  /**
3
3
  * {{.DisplayName}} — Home page
4
+ *
5
+ * Host-provided packages (vue, pinia, @vueuse/core, @construct/sdk, etc.)
6
+ * are available as imports — they resolve to the host at runtime.
4
7
  */
8
+ import { ref } from 'vue'
9
+
10
+ const greeting = ref('Your space is ready. Start building!')
5
11
  </script>
6
12
 
7
13
  <template>
8
14
  <div class="h-full flex items-center justify-center">
9
15
  <div class="text-center">
10
16
  <h1 class="text-2xl font-bold text-[var(--app-foreground)] mb-2">{{.DisplayName}}</h1>
11
- <p class="text-sm text-[var(--app-muted)]">Your space is ready. Start building!</p>
17
+ <p class="text-sm text-[var(--app-muted)]">{{ greeting }}</p>
12
18
  </div>
13
19
  </div>
14
20
  </template>
@@ -4,20 +4,24 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
+ "generate-entry": "construct build --entry-only",
7
8
  "build": "construct build",
8
9
  "dev": "construct dev",
9
- "check": "construct check"
10
+ "check": "construct check",
11
+ "validate": "construct validate"
10
12
  },
11
13
  "peerDependencies": {
12
- "vue": "^3.5.0"
13
- },
14
- "dependencies": {
15
- "@construct-space/ui": "^0.3.5"
14
+ "vue": "^3.5.0",
15
+ "pinia": "^3.0.0",
16
+ "@vueuse/core": "^14.0.0"
16
17
  },
17
18
  "devDependencies": {
18
- "vite": "^8.0.0",
19
+ "@construct-space/cli": "latest",
20
+ "@construct-space/sdk": "latest",
19
21
  "@vitejs/plugin-vue": "^5.2.3",
20
- "typescript": "^6.0.0",
22
+ "lucide-vue-next": "^1.0.0",
23
+ "typescript": "^5.9.3",
24
+ "vite": "^6.3.5",
21
25
  "vue-tsc": "^3.2.5"
22
26
  }
23
27
  }
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "icon": "i-lucide-box",
10
10
  "scope": "both",
11
- "minConstructVersion": "0.2.0",
11
+ "minConstructVersion": "0.7.0",
12
12
  "navigation": {
13
13
  "label": "{{.DisplayName}}",
14
14
  "icon": "i-lucide-box",
@@ -34,6 +34,7 @@
34
34
  "keywords": ["{{.ID}}"],
35
35
  "agent": "agent/config.md",
36
36
  "skills": ["agent/skills/default.md"],
37
+ "actions": "src/actions.ts",
37
38
  "widgets": [
38
39
  {
39
40
  "id": "summary",
@@ -9,18 +9,13 @@
9
9
  "esModuleInterop": true,
10
10
  "skipLibCheck": true,
11
11
  "paths": {
12
- "@construct/sdk": ["../construct-sdk/src/index.ts"]
12
+ "@/*": ["./src/*"],
13
+ "@construct/sdk": ["./node_modules/@construct-space/sdk/src/index.ts"]
13
14
  }
14
15
  },
15
16
  "include": [
16
17
  "src/**/*.ts",
17
- "pages/**/*.vue",
18
- "components/**/*.vue",
19
- "composables/**/*.ts",
20
- "utils/**/*.ts",
21
- "types/**/*.ts",
22
- "types.ts",
23
- "auto-imports.d.ts",
24
- "components.d.ts"
18
+ "src/**/*.vue",
19
+ "widgets/**/*.vue"
25
20
  ]
26
21
  }
@@ -2,6 +2,49 @@ import { defineConfig } from 'vite'
2
2
  import vue from '@vitejs/plugin-vue'
3
3
  import { resolve } from 'path'
4
4
 
5
+ /**
6
+ * Host-provided externals — these are supplied by Construct at runtime
7
+ * via window.__CONSTRUCT__. Do NOT bundle them; they must stay external.
8
+ *
9
+ * Full list lives in: construct-app/frontend/lib/spaceHost.ts
10
+ */
11
+ const hostExternals = [
12
+ 'vue',
13
+ 'vue-router',
14
+ 'pinia',
15
+ '@vueuse/core',
16
+ '@vueuse/integrations',
17
+ '@tauri-apps/api',
18
+ '@tauri-apps/api/core',
19
+ '@tauri-apps/api/path',
20
+ '@tauri-apps/api/event',
21
+ '@tauri-apps/api/webview',
22
+ '@tauri-apps/plugin-fs',
23
+ '@tauri-apps/plugin-shell',
24
+ '@tauri-apps/plugin-dialog',
25
+ '@tauri-apps/plugin-process',
26
+ 'lucide-vue-next',
27
+ 'date-fns',
28
+ 'dexie',
29
+ 'zod',
30
+ '@construct-space/ui',
31
+ '@construct/sdk',
32
+ '@construct-space/sdk',
33
+ ]
34
+
35
+ function makeGlobals(externals: string[]): Record<string, string> {
36
+ const globals: Record<string, string> = {}
37
+ for (const ext of externals) {
38
+ // Simple ids use dot access, scoped/slashed ids use bracket access
39
+ if (/^[a-z]+$/.test(ext)) {
40
+ globals[ext] = `window.__CONSTRUCT__.${ext}`
41
+ } else {
42
+ globals[ext] = `window.__CONSTRUCT__["${ext}"]`
43
+ }
44
+ }
45
+ return globals
46
+ }
47
+
5
48
  export default defineConfig({
6
49
  plugins: [vue()],
7
50
  build: {
@@ -12,14 +55,9 @@ export default defineConfig({
12
55
  formats: ['iife'],
13
56
  },
14
57
  rollupOptions: {
15
- external: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
58
+ external: hostExternals,
16
59
  output: {
17
- globals: {
18
- vue: 'window.__CONSTRUCT__.vue',
19
- 'vue-router': 'window.__CONSTRUCT__["vue-router"]',
20
- pinia: 'window.__CONSTRUCT__.pinia',
21
- '@vueuse/core': 'window.__CONSTRUCT__["@vueuse/core"]',
22
- },
60
+ globals: makeGlobals(hostExternals),
23
61
  },
24
62
  },
25
63
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@construct-space/cli",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Construct CLI — scaffold, build, develop, and publish spaces",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,6 +18,7 @@
18
18
  "scripts": {
19
19
  "build": "bun build src/index.ts --outdir dist --target node --format esm && cp -r templates dist/",
20
20
  "dev": "bun run src/index.ts",
21
+ "test": "bun test",
21
22
  "typecheck": "tsc --noEmit"
22
23
  },
23
24
  "dependencies": {
@@ -25,10 +26,10 @@
25
26
  "@inquirer/prompts": "^8.3.2",
26
27
  "chalk": "^5.6.2",
27
28
  "ora": "^9.3.0",
28
- "chokidar": "^4.0.3"
29
+ "chokidar": "^5.0.0"
29
30
  },
30
31
  "devDependencies": {
31
- "@types/node": "^22.15.17",
32
+ "@types/node": "^25.5.0",
32
33
  "typescript": "^6.0.2"
33
34
  },
34
35
  "keywords": [
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Space Actions — exposed to the AI agent via space_run_action
3
+ *
4
+ * Define actions here and they'll be automatically available as agent tools.
5
+ * The agent calls: space_run_action(action: "action_id", payload: {...})
6
+ */
7
+
8
+ // --- Graph SDK (data layer) ---
9
+ // Uncomment after running `construct graph init` and defining models:
10
+ //
11
+ // import { useGraph } from '@construct-space/graph'
12
+ // const graph = useGraph()
13
+ //
14
+ // Example action using Graph:
15
+ // fetchItems: {
16
+ // description: 'Fetch items from the graph',
17
+ // params: {
18
+ // limit: { type: 'number', description: 'Max items to return', required: false },
19
+ // },
20
+ // run: async (p: any) => {
21
+ // const items = await graph.query('Item').limit(p.limit ?? 10).exec()
22
+ // return { items }
23
+ // },
24
+ // },
25
+
26
+ export const actions = {
27
+ // Example action:
28
+ // hello: {
29
+ // description: 'Say hello',
30
+ // params: {
31
+ // name: { type: 'string', description: 'Name to greet', required: true },
32
+ // },
33
+ // run: (p: any) => ({ message: `Hello ${p.name}!` }),
34
+ // },
35
+ }
@@ -4,14 +4,20 @@ name: {{.DisplayName}}
4
4
  category: space
5
5
  description: AI agent for the {{.DisplayName}} space
6
6
  maxIterations: 15
7
+ tools: []
7
8
  canInvokeAgents: []
8
9
  ---
9
10
 
10
- You are Construct's {{.DisplayName}} agent. You help users work effectively within the {{.DisplayName}} space.
11
+ You are Construct's {{.DisplayName}} agent. You help users work within the {{.DisplayName}} space.
12
+
13
+ ## Context
14
+
15
+ Use space_list_actions to discover available actions for this space.
16
+ Use space_run_action to execute actions.
17
+ Do NOT call get_project_context — you work with space content, not project files.
11
18
 
12
19
  ## Behavior
13
20
 
14
- - Use get_project_context to understand the current project before acting
15
- - Read files before modifying them
16
- - Focus on tasks relevant to this space
21
+ - Start by listing available actions to understand what you can do
17
22
  - Be concise and action-oriented
23
+ - Focus on tasks relevant to this space
@@ -0,0 +1,14 @@
1
+ // Space entry — exports pages, widgets, and actions for the host loader.
2
+ // `construct dev` regenerates this from space.manifest.json on changes.
3
+ import IndexPage from './pages/index.vue'
4
+ import { actions } from './actions'
5
+
6
+ const spaceExport = {
7
+ pages: {
8
+ '': IndexPage,
9
+ },
10
+ widgets: {},
11
+ actions,
12
+ }
13
+
14
+ export default spaceExport
@@ -0,0 +1,16 @@
1
+ // Space entry — exports pages, widgets, and actions for the host loader.
2
+ // `construct dev` regenerates this from space.manifest.json on changes.
3
+ import IndexPage from './pages/index.vue'
4
+ import SettingsPage from './pages/settings.vue'
5
+ import { actions } from './actions'
6
+
7
+ const spaceExport = {
8
+ pages: {
9
+ '': IndexPage,
10
+ 'settings': SettingsPage,
11
+ },
12
+ widgets: {},
13
+ actions,
14
+ }
15
+
16
+ export default spaceExport
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * {{.DisplayName}} — Settings page
4
+ */
5
+ import { ref } from 'vue'
6
+
7
+ const autoSave = ref(true)
8
+ const theme = ref<'system' | 'light' | 'dark'>('system')
9
+ </script>
10
+
11
+ <template>
12
+ <div class="h-full overflow-auto p-6">
13
+ <h1 class="text-xl font-bold text-[var(--app-foreground)] mb-6">Settings</h1>
14
+
15
+ <div class="space-y-4 max-w-md">
16
+ <label class="flex items-center justify-between">
17
+ <span class="text-sm text-[var(--app-foreground)]">Auto-save</span>
18
+ <input v-model="autoSave" type="checkbox" class="rounded" />
19
+ </label>
20
+
21
+ <label class="block">
22
+ <span class="text-sm text-[var(--app-foreground)] block mb-1">Theme</span>
23
+ <select v-model="theme" class="w-full rounded border border-[var(--app-border)] bg-[var(--app-background)] px-3 py-1.5 text-sm">
24
+ <option value="system">System</option>
25
+ <option value="light">Light</option>
26
+ <option value="dark">Dark</option>
27
+ </select>
28
+ </label>
29
+ </div>
30
+ </div>
31
+ </template>
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: {{.ID}}-data
3
+ name: {{.DisplayName}} Data Management
4
+ description: Skill for managing {{.DisplayName}} data and content
5
+ trigger: {{.ID}} data|content|manage
6
+ category: space
7
+ tools: [read_file, list_dir, glob, grep, write_file]
8
+ ---
9
+
10
+ # {{.DisplayName}} Data Management Skill
11
+
12
+ This skill handles data operations for the {{.DisplayName}} space.
13
+
14
+ ## Instructions
15
+ - Help users create, read, update, and delete content
16
+ - Validate data before writing
17
+ - Use the space actions API when available
18
+ - Prefer batch operations for bulk changes
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: {{.ID}}-ui
3
+ name: {{.DisplayName}} UI Customization
4
+ description: Skill for customizing the {{.DisplayName}} user interface
5
+ trigger: {{.ID}} ui|layout|design|style
6
+ category: space
7
+ tools: [read_file, write_file, glob]
8
+ ---
9
+
10
+ # {{.DisplayName}} UI Customization Skill
11
+
12
+ This skill helps customize the {{.DisplayName}} space interface.
13
+
14
+ ## Instructions
15
+ - Help users adjust layout and styling
16
+ - Use Construct CSS variables (--app-foreground, --app-background, --app-accent, etc.)
17
+ - Follow the host design system conventions
18
+ - Suggest accessible color combinations
@@ -0,0 +1,60 @@
1
+ {
2
+ "id": "{{.ID}}",
3
+ "name": "{{.DisplayName}}",
4
+ "version": "0.1.0",
5
+ "description": "{{.DisplayName}} space for Construct",
6
+ "author": {
7
+ "name": "Your Name"
8
+ },
9
+ "icon": "i-lucide-box",
10
+ "scope": "both",
11
+ "minConstructVersion": "0.7.0",
12
+ "navigation": {
13
+ "label": "{{.DisplayName}}",
14
+ "icon": "i-lucide-box",
15
+ "to": "{{.ID}}",
16
+ "order": 100
17
+ },
18
+ "pages": [
19
+ {
20
+ "path": "",
21
+ "label": "Home",
22
+ "icon": "i-lucide-home",
23
+ "default": true
24
+ },
25
+ {
26
+ "path": "settings",
27
+ "label": "Settings",
28
+ "icon": "i-lucide-settings"
29
+ }
30
+ ],
31
+ "toolbar": [
32
+ {
33
+ "id": "{{.ID}}-new",
34
+ "icon": "i-lucide-plus",
35
+ "label": "New {{.DisplayName}}",
36
+ "action": "create{{.DisplayNameNoSpace}}"
37
+ }
38
+ ],
39
+ "keywords": ["{{.ID}}"],
40
+ "agent": "agent/config.md",
41
+ "skills": [
42
+ "agent/skills/default.md",
43
+ "agent/skills/data.md",
44
+ "agent/skills/ui.md"
45
+ ],
46
+ "actions": "src/actions.ts",
47
+ "widgets": [
48
+ {
49
+ "id": "summary",
50
+ "name": "{{.DisplayName}} Summary",
51
+ "description": "Quick summary widget for {{.DisplayName}}",
52
+ "icon": "i-lucide-box",
53
+ "defaultSize": "4x1",
54
+ "sizes": {
55
+ "2x1": "widgets/summary/2x1.vue",
56
+ "4x1": "widgets/summary/4x1.vue"
57
+ }
58
+ }
59
+ ]
60
+ }
@@ -1,14 +1,20 @@
1
1
  <script setup lang="ts">
2
2
  /**
3
3
  * {{.DisplayName}} — Home page
4
+ *
5
+ * Host-provided packages (vue, pinia, @vueuse/core, @construct/sdk, etc.)
6
+ * are available as imports — they resolve to the host at runtime.
4
7
  */
8
+ import { ref } from 'vue'
9
+
10
+ const greeting = ref('Your space is ready. Start building!')
5
11
  </script>
6
12
 
7
13
  <template>
8
14
  <div class="h-full flex items-center justify-center">
9
15
  <div class="text-center">
10
16
  <h1 class="text-2xl font-bold text-[var(--app-foreground)] mb-2">{{.DisplayName}}</h1>
11
- <p class="text-sm text-[var(--app-muted)]">Your space is ready. Start building!</p>
17
+ <p class="text-sm text-[var(--app-muted)]">{{ greeting }}</p>
12
18
  </div>
13
19
  </div>
14
20
  </template>