@construct-space/cli 1.1.11 → 1.1.12

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 (2) hide show
  1. package/dist/index.js +711 -91
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -4613,18 +4613,616 @@ function runHook(hooks, hookName, root) {
4613
4613
  execSync2(cmd, { cwd: root, stdio: "inherit" });
4614
4614
  }
4615
4615
 
4616
+ // src/lib/embedded-templates.ts
4617
+ var EMBEDDED_TEMPLATES = {
4618
+ "package.json.tmpl": `{
4619
+ "name": "@construct-spaces/{{.Name}}",
4620
+ "version": "0.1.0",
4621
+ "private": true,
4622
+ "type": "module",
4623
+ "scripts": {
4624
+ "generate-entry": "construct build --entry-only",
4625
+ "build": "construct build",
4626
+ "dev": "construct dev",
4627
+ "check": "construct check",
4628
+ "validate": "construct validate"
4629
+ },
4630
+ "peerDependencies": {
4631
+ "vue": "^3.5.0",
4632
+ "pinia": "^3.0.0",
4633
+ "@vueuse/core": "^14.0.0"
4634
+ },
4635
+ "devDependencies": {
4636
+ "@construct-space/cli": "latest",
4637
+ "@construct-space/sdk": "latest",
4638
+ "@vitejs/plugin-vue": "^5.2.3",
4639
+ "lucide-vue-next": "^1.0.0",
4640
+ "typescript": "^5.9.3",
4641
+ "vite": "^6.3.5",
4642
+ "vue-tsc": "^3.2.5"
4643
+ }
4644
+ }
4645
+ `,
4646
+ "config.md.tmpl": `---
4647
+ id: {{.ID}}
4648
+ name: {{.DisplayName}}
4649
+ category: space
4650
+ description: AI agent for the {{.DisplayName}} space
4651
+ maxIterations: 15
4652
+ tools: []
4653
+ canInvokeAgents: []
4654
+ ---
4655
+
4656
+ You are Construct's {{.DisplayName}} agent. You help users work within the {{.DisplayName}} space.
4657
+
4658
+ ## Context
4659
+
4660
+ Use space_list_actions to discover available actions for this space.
4661
+ Use space_run_action to execute actions.
4662
+ Do NOT call get_project_context \u2014 you work with space content, not project files.
4663
+
4664
+ ## Behavior
4665
+
4666
+ - Start by listing available actions to understand what you can do
4667
+ - Be concise and action-oriented
4668
+ - Focus on tasks relevant to this space
4669
+ `,
4670
+ "full/skill-data.md.tmpl": `---
4671
+ id: {{.ID}}-data
4672
+ name: {{.DisplayName}} Data Management
4673
+ description: Skill for managing {{.DisplayName}} data and content
4674
+ trigger: {{.ID}} data|content|manage
4675
+ category: space
4676
+ tools: [read_file, list_dir, glob, grep, write_file]
4677
+ ---
4678
+
4679
+ # {{.DisplayName}} Data Management Skill
4680
+
4681
+ This skill handles data operations for the {{.DisplayName}} space.
4682
+
4683
+ ## Instructions
4684
+ - Help users create, read, update, and delete content
4685
+ - Validate data before writing
4686
+ - Use the space actions API when available
4687
+ - Prefer batch operations for bulk changes
4688
+ `,
4689
+ "full/entry.ts.tmpl": `// Space entry \u2014 exports pages, widgets, and actions for the host loader.
4690
+ // \`construct dev\` regenerates this from space.manifest.json on changes.
4691
+ import IndexPage from './pages/index.vue'
4692
+ import SettingsPage from './pages/settings.vue'
4693
+ import { actions } from './actions'
4694
+
4695
+ const spaceExport = {
4696
+ pages: {
4697
+ '': IndexPage,
4698
+ 'settings': SettingsPage,
4699
+ },
4700
+ widgets: {},
4701
+ actions,
4702
+ }
4703
+
4704
+ export default spaceExport
4705
+ `,
4706
+ "full/skill-ui.md.tmpl": `---
4707
+ id: {{.ID}}-ui
4708
+ name: {{.DisplayName}} UI Customization
4709
+ description: Skill for customizing the {{.DisplayName}} user interface
4710
+ trigger: {{.ID}} ui|layout|design|style
4711
+ category: space
4712
+ tools: [read_file, write_file, glob]
4713
+ ---
4714
+
4715
+ # {{.DisplayName}} UI Customization Skill
4716
+
4717
+ This skill helps customize the {{.DisplayName}} space interface.
4718
+
4719
+ ## Instructions
4720
+ - Help users adjust layout and styling
4721
+ - Use Construct CSS variables (--app-foreground, --app-background, --app-accent, etc.)
4722
+ - Follow the host design system conventions
4723
+ - Suggest accessible color combinations
4724
+ `,
4725
+ "full/space.manifest.json.tmpl": `{
4726
+ "id": "{{.ID}}",
4727
+ "name": "{{.DisplayName}}",
4728
+ "version": "0.1.0",
4729
+ "description": "{{.DisplayName}} space for Construct",
4730
+ "author": {
4731
+ "name": "Your Name"
4732
+ },
4733
+ "icon": "i-lucide-box",
4734
+ "scope": "both",
4735
+ "minConstructVersion": "0.7.0",
4736
+ "navigation": {
4737
+ "label": "{{.DisplayName}}",
4738
+ "icon": "i-lucide-box",
4739
+ "to": "{{.ID}}",
4740
+ "order": 100
4741
+ },
4742
+ "pages": [
4743
+ {
4744
+ "path": "",
4745
+ "label": "Home",
4746
+ "icon": "i-lucide-home",
4747
+ "default": true
4748
+ },
4749
+ {
4750
+ "path": "settings",
4751
+ "label": "Settings",
4752
+ "icon": "i-lucide-settings"
4753
+ }
4754
+ ],
4755
+ "toolbar": [
4756
+ {
4757
+ "id": "{{.ID}}-new",
4758
+ "icon": "i-lucide-plus",
4759
+ "label": "New {{.DisplayName}}",
4760
+ "action": "create{{.DisplayNameNoSpace}}"
4761
+ }
4762
+ ],
4763
+ "keywords": ["{{.ID}}"],
4764
+ "agent": "agent/config.md",
4765
+ "skills": [
4766
+ "agent/skills/default.md",
4767
+ "agent/skills/data.md",
4768
+ "agent/skills/ui.md"
4769
+ ],
4770
+ "actions": "src/actions.ts",
4771
+ "widgets": [
4772
+ {
4773
+ "id": "summary",
4774
+ "name": "{{.DisplayName}} Summary",
4775
+ "description": "Quick summary widget for {{.DisplayName}}",
4776
+ "icon": "i-lucide-box",
4777
+ "defaultSize": "4x1",
4778
+ "sizes": {
4779
+ "2x1": "widgets/summary/2x1.vue",
4780
+ "4x1": "widgets/summary/4x1.vue"
4781
+ }
4782
+ }
4783
+ ]
4784
+ }
4785
+ `,
4786
+ "full/settings.vue.tmpl": `<script setup lang="ts">
4787
+ /**
4788
+ * {{.DisplayName}} \u2014 Settings page
4789
+ */
4790
+ import { ref } from 'vue'
4791
+
4792
+ const autoSave = ref(true)
4793
+ const theme = ref<'system' | 'light' | 'dark'>('system')
4794
+ </script>
4795
+
4796
+ <template>
4797
+ <div class="h-full overflow-auto p-6">
4798
+ <h1 class="text-xl font-bold text-[var(--app-foreground)] mb-6">Settings</h1>
4799
+
4800
+ <div class="space-y-4 max-w-md">
4801
+ <label class="flex items-center justify-between">
4802
+ <span class="text-sm text-[var(--app-foreground)]">Auto-save</span>
4803
+ <input v-model="autoSave" type="checkbox" class="rounded" />
4804
+ </label>
4805
+
4806
+ <label class="block">
4807
+ <span class="text-sm text-[var(--app-foreground)] block mb-1">Theme</span>
4808
+ <select v-model="theme" class="w-full rounded border border-[var(--app-border)] bg-[var(--app-background)] px-3 py-1.5 text-sm">
4809
+ <option value="system">System</option>
4810
+ <option value="light">Light</option>
4811
+ <option value="dark">Dark</option>
4812
+ </select>
4813
+ </label>
4814
+ </div>
4815
+ </div>
4816
+ </template>
4817
+ `,
4818
+ "vite.config.ts.tmpl": `import { defineConfig } from 'vite'
4819
+ import vue from '@vitejs/plugin-vue'
4820
+ import { resolve } from 'path'
4821
+
4822
+ /**
4823
+ * Host-provided externals \u2014 these are supplied by Construct at runtime
4824
+ * via window.__CONSTRUCT__. Do NOT bundle them; they must stay external.
4825
+ *
4826
+ * Full list lives in: construct-app/frontend/lib/spaceHost.ts
4827
+ */
4828
+ const hostExternals = [
4829
+ 'vue',
4830
+ 'vue-router',
4831
+ 'pinia',
4832
+ '@vueuse/core',
4833
+ '@vueuse/integrations',
4834
+ '@tauri-apps/api',
4835
+ '@tauri-apps/api/core',
4836
+ '@tauri-apps/api/path',
4837
+ '@tauri-apps/api/event',
4838
+ '@tauri-apps/api/webview',
4839
+ '@tauri-apps/plugin-fs',
4840
+ '@tauri-apps/plugin-shell',
4841
+ '@tauri-apps/plugin-dialog',
4842
+ '@tauri-apps/plugin-process',
4843
+ 'lucide-vue-next',
4844
+ 'date-fns',
4845
+ 'dexie',
4846
+ 'zod',
4847
+ '@construct-space/ui',
4848
+ '@construct/sdk',
4849
+ '@construct-space/sdk',
4850
+ ]
4851
+
4852
+ function makeGlobals(externals: string[]): Record<string, string> {
4853
+ const globals: Record<string, string> = {}
4854
+ for (const ext of externals) {
4855
+ // Simple ids use dot access, scoped/slashed ids use bracket access
4856
+ if (/^[a-z]+$/.test(ext)) {
4857
+ globals[ext] = \`window.__CONSTRUCT__.\${ext}\`
4858
+ } else {
4859
+ globals[ext] = \`window.__CONSTRUCT__["\${ext}"]\`
4860
+ }
4861
+ }
4862
+ return globals
4863
+ }
4864
+
4865
+ export default defineConfig({
4866
+ plugins: [vue()],
4867
+ build: {
4868
+ lib: {
4869
+ entry: resolve(__dirname, 'src/entry.ts'),
4870
+ name: '__CONSTRUCT_SPACE_{{.IDUpper}}',
4871
+ fileName: 'space-{{.ID}}',
4872
+ formats: ['iife'],
4873
+ },
4874
+ rollupOptions: {
4875
+ external: hostExternals,
4876
+ output: {
4877
+ globals: makeGlobals(hostExternals),
4878
+ },
4879
+ },
4880
+ },
4881
+ resolve: {
4882
+ alias: {
4883
+ '~': resolve(__dirname),
4884
+ '@': resolve(__dirname, 'src'),
4885
+ },
4886
+ },
4887
+ })
4888
+ `,
4889
+ "index.vue.tmpl": `<script setup lang="ts">
4890
+ /**
4891
+ * {{.DisplayName}} \u2014 Home page
4892
+ *
4893
+ * Host-provided packages (vue, pinia, @vueuse/core, @construct/sdk, etc.)
4894
+ * are available as imports \u2014 they resolve to the host at runtime.
4895
+ */
4896
+ import { ref } from 'vue'
4897
+
4898
+ const greeting = ref('Your space is ready. Start building!')
4899
+ </script>
4900
+
4901
+ <template>
4902
+ <div class="h-full flex items-center justify-center">
4903
+ <div class="text-center">
4904
+ <h1 class="text-2xl font-bold text-[var(--app-foreground)] mb-2">{{.DisplayName}}</h1>
4905
+ <p class="text-sm text-[var(--app-muted)]">{{ greeting }}</p>
4906
+ </div>
4907
+ </div>
4908
+ </template>
4909
+ `,
4910
+ "entry.ts.tmpl": `// Space entry \u2014 exports pages, widgets, and actions for the host loader.
4911
+ // \`construct dev\` regenerates this from space.manifest.json on changes.
4912
+ import IndexPage from './pages/index.vue'
4913
+ import { actions } from './actions'
4914
+
4915
+ const spaceExport = {
4916
+ pages: {
4917
+ '': IndexPage,
4918
+ },
4919
+ widgets: {},
4920
+ actions,
4921
+ }
4922
+
4923
+ export default spaceExport
4924
+ `,
4925
+ "space.manifest.json.tmpl": `{
4926
+ "id": "{{.ID}}",
4927
+ "name": "{{.DisplayName}}",
4928
+ "version": "0.1.0",
4929
+ "description": "{{.DisplayName}} space for Construct",
4930
+ "author": {
4931
+ "name": "Your Name"
4932
+ },
4933
+ "icon": "i-lucide-box",
4934
+ "scope": "both",
4935
+ "minConstructVersion": "0.7.0",
4936
+ "navigation": {
4937
+ "label": "{{.DisplayName}}",
4938
+ "icon": "i-lucide-box",
4939
+ "to": "{{.ID}}",
4940
+ "order": 100
4941
+ },
4942
+ "pages": [
4943
+ {
4944
+ "path": "",
4945
+ "label": "Home",
4946
+ "icon": "i-lucide-home",
4947
+ "default": true
4948
+ }
4949
+ ],
4950
+ "toolbar": [
4951
+ {
4952
+ "id": "{{.ID}}-new",
4953
+ "icon": "i-lucide-plus",
4954
+ "label": "New {{.DisplayName}}",
4955
+ "action": "create{{.DisplayNameNoSpace}}"
4956
+ }
4957
+ ],
4958
+ "keywords": ["{{.ID}}"],
4959
+ "agent": "agent/config.md",
4960
+ "skills": ["agent/skills/default.md"],
4961
+ "actions": {},
4962
+ "widgets": [
4963
+ {
4964
+ "id": "summary",
4965
+ "name": "{{.DisplayName}} Summary",
4966
+ "description": "Quick summary widget for {{.DisplayName}}",
4967
+ "icon": "i-lucide-box",
4968
+ "defaultSize": "4x1",
4969
+ "sizes": {
4970
+ "2x1": "widgets/summary/2x1.vue",
4971
+ "4x1": "widgets/summary/4x1.vue"
4972
+ }
4973
+ }
4974
+ ]
4975
+ }
4976
+ `,
4977
+ "skill.md.tmpl": `---
4978
+ id: {{.ID}}-default
4979
+ name: {{.DisplayName}} Basics
4980
+ description: Default skill for {{.DisplayName}} space
4981
+ trigger: {{.ID}}|help
4982
+ category: space
4983
+ tools: [read_file, list_dir, glob, grep]
4984
+ ---
4985
+
4986
+ # {{.DisplayName}} Space Skill
4987
+
4988
+ This skill provides default behavior for the {{.DisplayName}} space.
4989
+
4990
+ ## Instructions
4991
+ - Assist with {{.DisplayName}}-related tasks
4992
+ - Follow project conventions
4993
+ - Read relevant files before making suggestions
4994
+ `,
4995
+ "gitignore.tmpl": `node_modules/
4996
+ dist/
4997
+ src/entry.ts
4998
+ *.local
4999
+ .DS_Store
5000
+ `,
5001
+ "actions.ts.tmpl": `/**
5002
+ * Space Actions \u2014 exposed to the AI agent via space_run_action
5003
+ *
5004
+ * Define actions here and they'll be automatically available as agent tools.
5005
+ * The agent calls: space_run_action(action: "action_id", payload: {...})
5006
+ */
5007
+
5008
+ // --- Graph SDK (data layer) ---
5009
+ // Uncomment after running \`construct graph init\` and defining models:
5010
+ //
5011
+ // import { useGraph } from '@construct-space/graph'
5012
+ // const graph = useGraph()
5013
+ //
5014
+ // Example action using Graph:
5015
+ // fetchItems: {
5016
+ // description: 'Fetch items from the graph',
5017
+ // params: {
5018
+ // limit: { type: 'number', description: 'Max items to return', required: false },
5019
+ // },
5020
+ // run: async (p: any) => {
5021
+ // const items = await graph.query('Item').limit(p.limit ?? 10).exec()
5022
+ // return { items }
5023
+ // },
5024
+ // },
5025
+
5026
+ export const actions = {
5027
+ // Example action:
5028
+ // hello: {
5029
+ // description: 'Say hello',
5030
+ // params: {
5031
+ // name: { type: 'string', description: 'Name to greet', required: true },
5032
+ // },
5033
+ // run: (p: any) => ({ message: \`Hello \${p.name}!\` }),
5034
+ // },
5035
+ }
5036
+ `,
5037
+ "readme.md.tmpl": `# {{.DisplayName}}
5038
+
5039
+ A Construct space.
5040
+
5041
+ ## Development
5042
+
5043
+ \`\`\`bash
5044
+ bun install
5045
+ construct space dev
5046
+ \`\`\`
5047
+
5048
+ ## Build
5049
+
5050
+ \`\`\`bash
5051
+ construct space build
5052
+ \`\`\`
5053
+
5054
+ Output goes to \`dist/\`.
5055
+ `,
5056
+ "safety.json.tmpl": `{
5057
+ "hooks": [
5058
+ {
5059
+ "id": "{{.ID}}-no-rm-rf",
5060
+ "type": "pre_tool",
5061
+ "tools": ["bash"],
5062
+ "command": "if echo \\"$TOOL_INPUT\\" | grep -qE 'rm\\\\s+-rf\\\\s+/'; then\\n echo '{\\"block\\":true,\\"message\\":\\"Blocked: rm -rf with absolute root path\\"}'\\nfi",
5063
+ "source": "space:{{.ID}}"
5064
+ }
5065
+ ]
5066
+ }
5067
+ `,
5068
+ "e2e/playwright.config.ts.tmpl": `import { defineConfig } from '@playwright/test'
5069
+
5070
+ export default defineConfig({
5071
+ testDir: './e2e',
5072
+ timeout: 30_000,
5073
+ retries: 0,
5074
+ use: {
5075
+ baseURL: 'http://localhost:5173',
5076
+ trace: 'on-first-retry',
5077
+ },
5078
+ webServer: {
5079
+ command: 'construct dev',
5080
+ port: 5173,
5081
+ reuseExistingServer: true,
5082
+ },
5083
+ })
5084
+ `,
5085
+ "e2e/space.spec.ts.tmpl": `import { test, expect } from '@playwright/test'
5086
+
5087
+ test.describe('{{.DisplayName}} space', () => {
5088
+ test('renders the default page', async ({ page }) => {
5089
+ await page.goto('/')
5090
+ await expect(page.locator('[data-testid="space-root"]')).toBeVisible()
5091
+ })
5092
+
5093
+ test('displays the space title', async ({ page }) => {
5094
+ await page.goto('/')
5095
+ await expect(page.locator('text={{.DisplayName}}')).toBeVisible()
5096
+ })
5097
+ })
5098
+ `,
5099
+ "build.yml.tmpl": `name: Build Space
5100
+
5101
+ on:
5102
+ push:
5103
+ tags:
5104
+ - 'v*'
5105
+ pull_request:
5106
+ branches: [main]
5107
+
5108
+ jobs:
5109
+ build:
5110
+ runs-on: ubuntu-latest
5111
+ steps:
5112
+ - uses: actions/checkout@v4
5113
+ - uses: oven-sh/setup-bun@v2
5114
+ with:
5115
+ bun-version: latest
5116
+ - run: bun install
5117
+ - run: bun run build
5118
+ - name: Upload artifacts
5119
+ if: startsWith(github.ref, 'refs/tags/v')
5120
+ uses: actions/upload-artifact@v4
5121
+ with:
5122
+ name: space-dist
5123
+ path: dist/
5124
+
5125
+ release:
5126
+ needs: build
5127
+ if: startsWith(github.ref, 'refs/tags/v')
5128
+ runs-on: ubuntu-latest
5129
+ permissions:
5130
+ contents: write
5131
+ steps:
5132
+ - uses: actions/download-artifact@v4
5133
+ with:
5134
+ name: space-dist
5135
+ path: dist/
5136
+ - run: tar -czf space-dist.tar.gz -C dist .
5137
+ - uses: softprops/action-gh-release@v2
5138
+ with:
5139
+ files: |
5140
+ space-dist.tar.gz
5141
+ dist/manifest.json
5142
+ generate_release_notes: true
5143
+ `,
5144
+ "widgets/2x1.vue.tmpl": `<script setup lang="ts">
5145
+ /**
5146
+ * {{.DisplayName}} Summary Widget \u2014 2\xD71 compact view
5147
+ */
5148
+ </script>
5149
+
5150
+ <template>
5151
+ <div class="h-full flex items-center gap-3 px-3">
5152
+ <div class="size-8 rounded-lg bg-[var(--app-accent)]/10 flex items-center justify-center">
5153
+ <Icon name="i-lucide-box" class="size-4 text-[var(--app-accent)]" />
5154
+ </div>
5155
+ <div class="min-w-0">
5156
+ <p class="text-sm font-medium text-[var(--app-foreground)] truncate">{{.DisplayName}}</p>
5157
+ <p class="text-xs text-[var(--app-muted)]">Ready</p>
5158
+ </div>
5159
+ </div>
5160
+ </template>
5161
+ `,
5162
+ "widgets/4x1.vue.tmpl": `<script setup lang="ts">
5163
+ /**
5164
+ * {{.DisplayName}} Summary Widget \u2014 4\xD71 wide view
5165
+ */
5166
+ </script>
5167
+
5168
+ <template>
5169
+ <div class="h-full flex items-center justify-between px-4">
5170
+ <div class="flex items-center gap-3">
5171
+ <div class="size-8 rounded-lg bg-[var(--app-accent)]/10 flex items-center justify-center">
5172
+ <Icon name="i-lucide-box" class="size-4 text-[var(--app-accent)]" />
5173
+ </div>
5174
+ <div>
5175
+ <p class="text-sm font-medium text-[var(--app-foreground)]">{{.DisplayName}}</p>
5176
+ <p class="text-xs text-[var(--app-muted)]">Your space is ready</p>
5177
+ </div>
5178
+ </div>
5179
+ <div class="text-right">
5180
+ <p class="text-lg font-bold text-[var(--app-foreground)]">0</p>
5181
+ <p class="text-[10px] text-[var(--app-muted)] uppercase">Items</p>
5182
+ </div>
5183
+ </div>
5184
+ </template>
5185
+ `,
5186
+ "tsconfig.json.tmpl": `{
5187
+ "compilerOptions": {
5188
+ "target": "ESNext",
5189
+ "module": "ESNext",
5190
+ "moduleResolution": "bundler",
5191
+ "strict": true,
5192
+ "jsx": "preserve",
5193
+ "noEmit": true,
5194
+ "esModuleInterop": true,
5195
+ "skipLibCheck": true,
5196
+ "paths": {
5197
+ "@/*": ["./src/*"],
5198
+ "@construct/sdk": ["./node_modules/@construct-space/sdk/src/index.ts"]
5199
+ }
5200
+ },
5201
+ "include": [
5202
+ "src/**/*.ts",
5203
+ "src/**/*.vue",
5204
+ "widgets/**/*.vue"
5205
+ ]
5206
+ }
5207
+ `
5208
+ };
5209
+
4616
5210
  // src/commands/scaffold.ts
4617
5211
  var nameRegex = /^[a-z][a-z0-9-]*$/;
4618
5212
  function render(template, data) {
4619
5213
  return template.replace(/\{\{\.Name\}\}/g, data.name).replace(/\{\{\.ID\}\}/g, data.id).replace(/\{\{\.IDUpper\}\}/g, data.idUpper).replace(/\{\{\.DisplayName\}\}/g, data.displayName).replace(/\{\{\.DisplayNameNoSpace\}\}/g, data.displayNameNoSpace);
4620
5214
  }
4621
5215
  function writeTemplate(templateDir, tmplName, outPath, data) {
5216
+ let content;
4622
5217
  const tmplPath = join2(templateDir, tmplName);
4623
- if (!existsSync2(tmplPath)) {
5218
+ if (existsSync2(tmplPath)) {
5219
+ content = readFileSync(tmplPath, "utf-8");
5220
+ } else if (EMBEDDED_TEMPLATES[tmplName] !== undefined) {
5221
+ content = EMBEDDED_TEMPLATES[tmplName];
5222
+ } else {
4624
5223
  console.warn(source_default.yellow(`Template not found: ${tmplName}`));
4625
5224
  return;
4626
5225
  }
4627
- const content = readFileSync(tmplPath, "utf-8");
4628
5226
  mkdirSync(dirname(outPath), { recursive: true });
4629
5227
  writeFileSync(outPath, render(content, data));
4630
5228
  }
@@ -7662,8 +8260,8 @@ async function build(options) {
7662
8260
  }
7663
8261
 
7664
8262
  // src/commands/dev.ts
7665
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
7666
- import { join as join9 } from "path";
8263
+ import { existsSync as existsSync8, readFileSync as readFileSync6, cpSync, mkdirSync as mkdirSync3 } from "fs";
8264
+ import { join as join10 } from "path";
7667
8265
  import { createHash as createHash2 } from "crypto";
7668
8266
 
7669
8267
  // node_modules/chokidar/esm/index.js
@@ -9236,11 +9834,55 @@ function watch(paths, options = {}) {
9236
9834
  return watcher;
9237
9835
  }
9238
9836
 
9837
+ // src/lib/appdir.ts
9838
+ import { join as join9 } from "path";
9839
+ import { homedir } from "os";
9840
+ import { platform as platform2 } from "process";
9841
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
9842
+ function dataDir() {
9843
+ if (process.env.CONSTRUCT_DATA_DIR)
9844
+ return process.env.CONSTRUCT_DATA_DIR;
9845
+ const home = homedir();
9846
+ switch (platform2) {
9847
+ case "darwin":
9848
+ return join9(home, "Library", "Application Support", "Construct");
9849
+ case "win32": {
9850
+ const appData = process.env.APPDATA || join9(home, "AppData", "Roaming");
9851
+ return join9(appData, "Construct");
9852
+ }
9853
+ default: {
9854
+ const xdg = process.env.XDG_DATA_HOME || join9(home, ".local", "share");
9855
+ return join9(xdg, "construct");
9856
+ }
9857
+ }
9858
+ }
9859
+ function activeProfileId() {
9860
+ try {
9861
+ const profilesPath = join9(dataDir(), "profiles.json");
9862
+ if (!existsSync7(profilesPath))
9863
+ return null;
9864
+ const data = JSON.parse(readFileSync5(profilesPath, "utf-8"));
9865
+ return data?.active_profile || null;
9866
+ } catch {
9867
+ return null;
9868
+ }
9869
+ }
9870
+ function spacesDir() {
9871
+ const profileId = activeProfileId();
9872
+ if (profileId) {
9873
+ return join9(dataDir(), "profiles", profileId, "spaces");
9874
+ }
9875
+ return join9(dataDir(), "spaces");
9876
+ }
9877
+ function spaceDir(spaceId) {
9878
+ return join9(spacesDir(), spaceId);
9879
+ }
9880
+
9239
9881
  // src/commands/dev.ts
9240
9882
  function getEntryWatchPaths(root) {
9241
9883
  return [
9242
- join9(root, MANIFEST_FILE),
9243
- join9(root, "src", "actions.ts")
9884
+ join10(root, MANIFEST_FILE),
9885
+ join10(root, "src", "actions.ts")
9244
9886
  ];
9245
9887
  }
9246
9888
  async function dev() {
@@ -9279,14 +9921,14 @@ async function dev() {
9279
9921
  }
9280
9922
  console.log(source_default.blue("Actions changed \u2014 entry regenerated"));
9281
9923
  });
9282
- const distDir = join9(root, "dist");
9283
- const bundleFile = join9(distDir, `space-${m.id}.iife.js`);
9924
+ const distDir = join10(root, "dist");
9925
+ const bundleFile = join10(distDir, `space-${m.id}.iife.js`);
9284
9926
  let lastChecksum = "";
9285
9927
  const distWatcher = watch(bundleFile, { ignoreInitial: false });
9286
9928
  distWatcher.on("all", () => {
9287
- if (!existsSync7(bundleFile))
9929
+ if (!existsSync8(bundleFile))
9288
9930
  return;
9289
- const bundleData = readFileSync5(bundleFile);
9931
+ const bundleData = readFileSync6(bundleFile);
9290
9932
  const checksum = createHash2("sha256").update(bundleData).digest("hex");
9291
9933
  if (checksum === lastChecksum)
9292
9934
  return;
@@ -9298,7 +9940,15 @@ async function dev() {
9298
9940
  hostApiVersion: "0.2.0",
9299
9941
  builtAt: new Date().toISOString()
9300
9942
  });
9301
- console.log(source_default.green(`Built \u2192 dist/ (${(bundleData.length / 1024).toFixed(1)} KB)`));
9943
+ try {
9944
+ const installDir = spaceDir(m.id);
9945
+ mkdirSync3(installDir, { recursive: true });
9946
+ cpSync(distDir, installDir, { recursive: true });
9947
+ console.log(source_default.green(`Built + installed \u2192 ${installDir} (${(bundleData.length / 1024).toFixed(1)} KB)`));
9948
+ } catch (err) {
9949
+ console.log(source_default.green(`Built \u2192 dist/ (${(bundleData.length / 1024).toFixed(1)} KB)`));
9950
+ console.log(source_default.yellow(` Install failed: ${err.message}`));
9951
+ }
9302
9952
  });
9303
9953
  console.log(source_default.green("Watching for changes... (Ctrl+C to stop)"));
9304
9954
  console.log(source_default.dim("Use the Preview button in Construct to open the Space Runner"));
@@ -9306,38 +9956,8 @@ async function dev() {
9306
9956
  }
9307
9957
 
9308
9958
  // src/commands/run.ts
9309
- import { existsSync as existsSync8, cpSync, mkdirSync as mkdirSync3 } from "fs";
9959
+ import { existsSync as existsSync9, cpSync as cpSync2, mkdirSync as mkdirSync4 } from "fs";
9310
9960
  import { join as join11 } from "path";
9311
-
9312
- // src/lib/appdir.ts
9313
- import { join as join10 } from "path";
9314
- import { homedir } from "os";
9315
- import { platform as platform2 } from "process";
9316
- function dataDir() {
9317
- if (process.env.CONSTRUCT_DATA_DIR)
9318
- return process.env.CONSTRUCT_DATA_DIR;
9319
- const home = homedir();
9320
- switch (platform2) {
9321
- case "darwin":
9322
- return join10(home, "Library", "Application Support", "Construct");
9323
- case "win32": {
9324
- const appData = process.env.APPDATA || join10(home, "AppData", "Roaming");
9325
- return join10(appData, "Construct");
9326
- }
9327
- default: {
9328
- const xdg = process.env.XDG_DATA_HOME || join10(home, ".local", "share");
9329
- return join10(xdg, "construct");
9330
- }
9331
- }
9332
- }
9333
- function spacesDir() {
9334
- return join10(dataDir(), "spaces");
9335
- }
9336
- function spaceDir(spaceId) {
9337
- return join10(spacesDir(), spaceId);
9338
- }
9339
-
9340
- // src/commands/run.ts
9341
9961
  function install() {
9342
9962
  const root = process.cwd();
9343
9963
  if (!exists(root)) {
@@ -9345,28 +9965,28 @@ function install() {
9345
9965
  process.exit(1);
9346
9966
  }
9347
9967
  const distDir = join11(root, "dist");
9348
- if (!existsSync8(distDir)) {
9968
+ if (!existsSync9(distDir)) {
9349
9969
  console.error(source_default.red("No dist/ directory found. Run 'construct build' first."));
9350
9970
  process.exit(1);
9351
9971
  }
9352
9972
  const m = read(root);
9353
9973
  const agentDir = join11(root, "agent");
9354
- if (existsSync8(agentDir)) {
9974
+ if (existsSync9(agentDir)) {
9355
9975
  bundleAgentDir(agentDir, distDir);
9356
9976
  }
9357
9977
  const installDir = spaceDir(m.id);
9358
- mkdirSync3(installDir, { recursive: true });
9359
- cpSync(distDir, installDir, { recursive: true });
9978
+ mkdirSync4(installDir, { recursive: true });
9979
+ cpSync2(distDir, installDir, { recursive: true });
9360
9980
  console.log(source_default.green(`Installed ${m.name} \u2192 ${installDir}`));
9361
9981
  console.log(source_default.dim(" Restart Construct to load the updated space."));
9362
9982
  }
9363
9983
 
9364
9984
  // src/commands/publish.ts
9365
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
9985
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
9366
9986
  import { join as join14, basename as basename6 } from "path";
9367
9987
 
9368
9988
  // src/lib/auth.ts
9369
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync, existsSync as existsSync9 } from "fs";
9989
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, unlinkSync, existsSync as existsSync10 } from "fs";
9370
9990
  import { join as join12, dirname as dirname4 } from "path";
9371
9991
  var CREDENTIALS_FILE = "credentials.json";
9372
9992
  var APP_PROFILES_FILE = "profiles.json";
@@ -9383,15 +10003,15 @@ function appProfileAuthPath(profileId) {
9383
10003
  function loadFromApp() {
9384
10004
  try {
9385
10005
  const profilesPath = appProfilesPath();
9386
- if (!existsSync9(profilesPath))
10006
+ if (!existsSync10(profilesPath))
9387
10007
  return null;
9388
- const profiles = JSON.parse(readFileSync6(profilesPath, "utf-8"));
10008
+ const profiles = JSON.parse(readFileSync7(profilesPath, "utf-8"));
9389
10009
  if (!profiles?.active_profile)
9390
10010
  return null;
9391
10011
  const authPath = appProfileAuthPath(profiles.active_profile);
9392
- if (!existsSync9(authPath))
10012
+ if (!existsSync10(authPath))
9393
10013
  return null;
9394
- const auth = JSON.parse(readFileSync6(authPath, "utf-8"));
10014
+ const auth = JSON.parse(readFileSync7(authPath, "utf-8"));
9395
10015
  if (!auth?.authenticated || !auth?.token)
9396
10016
  return null;
9397
10017
  return {
@@ -9409,7 +10029,7 @@ function loadFromApp() {
9409
10029
  }
9410
10030
  function store(creds) {
9411
10031
  const path = credentialsPath();
9412
- mkdirSync4(dirname4(path), { recursive: true });
10032
+ mkdirSync5(dirname4(path), { recursive: true });
9413
10033
  writeFileSync5(path, JSON.stringify(creds, null, 2) + `
9414
10034
  `, { mode: 384 });
9415
10035
  }
@@ -9418,10 +10038,10 @@ function load2() {
9418
10038
  if (fromApp)
9419
10039
  return fromApp;
9420
10040
  const path = credentialsPath();
9421
- if (!existsSync9(path)) {
10041
+ if (!existsSync10(path)) {
9422
10042
  throw new Error("not logged in \u2014 run 'construct login' first (or sign in to the Construct app)");
9423
10043
  }
9424
- const data = JSON.parse(readFileSync6(path, "utf-8"));
10044
+ const data = JSON.parse(readFileSync7(path, "utf-8"));
9425
10045
  if (!data.token) {
9426
10046
  throw new Error("not logged in \u2014 run 'construct login' first");
9427
10047
  }
@@ -9437,12 +10057,12 @@ function isAuthenticated() {
9437
10057
  }
9438
10058
  function clear() {
9439
10059
  const path = credentialsPath();
9440
- if (existsSync9(path))
10060
+ if (existsSync10(path))
9441
10061
  unlinkSync(path);
9442
10062
  }
9443
10063
 
9444
10064
  // src/lib/pack.ts
9445
- import { readdirSync as readdirSync3, statSync as statSync3, existsSync as existsSync10 } from "fs";
10065
+ import { readdirSync as readdirSync3, statSync as statSync3, existsSync as existsSync11 } from "fs";
9446
10066
  import { join as join13 } from "path";
9447
10067
  import { tmpdir } from "os";
9448
10068
  import { execSync as execSync3 } from "child_process";
@@ -9481,7 +10101,7 @@ async function packSource(root) {
9481
10101
  const tarballPath = join13(tmpdir(), `space-source-${Date.now()}.tar.gz`);
9482
10102
  const entries = [];
9483
10103
  for (const name of allowedRootFiles) {
9484
- if (existsSync10(join13(root, name)))
10104
+ if (existsSync11(join13(root, name)))
9485
10105
  entries.push(name);
9486
10106
  }
9487
10107
  for (const entry of readdirSync3(root)) {
@@ -9495,10 +10115,10 @@ async function packSource(root) {
9495
10115
  entries.push(entry);
9496
10116
  }
9497
10117
  for (const dir of allowedDirs) {
9498
- if (existsSync10(join13(root, dir)))
10118
+ if (existsSync11(join13(root, dir)))
9499
10119
  entries.push(dir);
9500
10120
  }
9501
- const validEntries = entries.filter((e) => existsSync10(join13(root, e)));
10121
+ const validEntries = entries.filter((e) => existsSync11(join13(root, e)));
9502
10122
  if (validEntries.length === 0) {
9503
10123
  throw new Error("No files to pack");
9504
10124
  }
@@ -9516,7 +10136,7 @@ async function packSource(root) {
9516
10136
  async function uploadSource(portalURL, token, tarballPath, m) {
9517
10137
  const formData = new FormData;
9518
10138
  formData.append("manifest", JSON.stringify(m));
9519
- const fileData = readFileSync7(tarballPath);
10139
+ const fileData = readFileSync8(tarballPath);
9520
10140
  const blob = new Blob([fileData]);
9521
10141
  formData.append("source", blob, basename6(tarballPath));
9522
10142
  const resp = await fetch(`${portalURL}/api/publish`, {
@@ -9540,7 +10160,7 @@ function setVersionInFiles(root, oldVer, newVer) {
9540
10160
  for (const file of ["package.json", "space.manifest.json"]) {
9541
10161
  const path = join14(root, file);
9542
10162
  try {
9543
- const data = readFileSync7(path, "utf-8");
10163
+ const data = readFileSync8(path, "utf-8");
9544
10164
  writeFileSync6(path, data.replace(oldStr, newStr));
9545
10165
  } catch {}
9546
10166
  }
@@ -9702,7 +10322,7 @@ async function publish(options) {
9702
10322
  }
9703
10323
 
9704
10324
  // src/commands/validate.ts
9705
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
10325
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
9706
10326
  import { join as join15 } from "path";
9707
10327
  function validate3() {
9708
10328
  const root = process.cwd();
@@ -9722,21 +10342,21 @@ function validate3() {
9722
10342
  for (const page of m.pages) {
9723
10343
  const component = page.component || (page.path === "" ? "pages/index.vue" : `pages/${page.path}.vue`);
9724
10344
  const fullPath = join15(root, "src", component);
9725
- if (!existsSync11(fullPath)) {
10345
+ if (!existsSync12(fullPath)) {
9726
10346
  console.log(source_default.yellow(` \u26A0 Page component not found: src/${component}`));
9727
10347
  warnings++;
9728
10348
  }
9729
10349
  }
9730
10350
  if (m.agent) {
9731
10351
  const agentPath = join15(root, m.agent);
9732
- if (!existsSync11(agentPath)) {
10352
+ if (!existsSync12(agentPath)) {
9733
10353
  console.log(source_default.yellow(` \u26A0 Agent config not found: ${m.agent}`));
9734
10354
  warnings++;
9735
10355
  }
9736
10356
  }
9737
10357
  const pkgPath = join15(root, "package.json");
9738
- if (existsSync11(pkgPath)) {
9739
- const pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
10358
+ if (existsSync12(pkgPath)) {
10359
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
9740
10360
  if (pkg.version && pkg.version !== m.version) {
9741
10361
  console.log(source_default.yellow(` \u26A0 Version mismatch: manifest=${m.version} package.json=${pkg.version}`));
9742
10362
  warnings++;
@@ -9751,7 +10371,7 @@ function validate3() {
9751
10371
 
9752
10372
  // src/commands/check.ts
9753
10373
  import { execSync as execSync4 } from "child_process";
9754
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
10374
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
9755
10375
  import { join as join16 } from "path";
9756
10376
  function check() {
9757
10377
  const root = process.cwd();
@@ -9771,18 +10391,18 @@ function check() {
9771
10391
  let warnings = 0;
9772
10392
  for (const page of m.pages) {
9773
10393
  const component = page.component || (page.path === "" ? "pages/index.vue" : `pages/${page.path}.vue`);
9774
- if (!existsSync12(join16(root, "src", component))) {
10394
+ if (!existsSync13(join16(root, "src", component))) {
9775
10395
  console.log(source_default.yellow(` \u26A0 Page not found: src/${component}`));
9776
10396
  warnings++;
9777
10397
  }
9778
10398
  }
9779
- if (m.agent && !existsSync12(join16(root, m.agent))) {
10399
+ if (m.agent && !existsSync13(join16(root, m.agent))) {
9780
10400
  console.log(source_default.yellow(` \u26A0 Agent config not found: ${m.agent}`));
9781
10401
  warnings++;
9782
10402
  }
9783
10403
  const pkgPath = join16(root, "package.json");
9784
- if (existsSync12(pkgPath)) {
9785
- const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
10404
+ if (existsSync13(pkgPath)) {
10405
+ const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
9786
10406
  if (pkg.version && pkg.version !== m.version) {
9787
10407
  console.log(source_default.yellow(` \u26A0 Version mismatch: manifest=${m.version} package.json=${pkg.version}`));
9788
10408
  warnings++;
@@ -9813,7 +10433,7 @@ function check() {
9813
10433
  }
9814
10434
 
9815
10435
  // src/commands/clean.ts
9816
- import { rmSync, existsSync as existsSync13 } from "fs";
10436
+ import { rmSync, existsSync as existsSync14 } from "fs";
9817
10437
  import { join as join17 } from "path";
9818
10438
  function clean(options) {
9819
10439
  const root = process.cwd();
@@ -9824,7 +10444,7 @@ function clean(options) {
9824
10444
  const lockfiles = ["bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
9825
10445
  for (const dir of dirs) {
9826
10446
  const path = join17(root, dir);
9827
- if (existsSync13(path)) {
10447
+ if (existsSync14(path)) {
9828
10448
  rmSync(path, { recursive: true });
9829
10449
  console.log(source_default.dim(` Removed ${dir}/`));
9830
10450
  }
@@ -9832,7 +10452,7 @@ function clean(options) {
9832
10452
  if (options?.all) {
9833
10453
  for (const file of lockfiles) {
9834
10454
  const path = join17(root, file);
9835
- if (existsSync13(path)) {
10455
+ if (existsSync14(path)) {
9836
10456
  rmSync(path);
9837
10457
  console.log(source_default.dim(` Removed ${file}`));
9838
10458
  }
@@ -10042,7 +10662,7 @@ function update() {
10042
10662
  }
10043
10663
 
10044
10664
  // src/commands/graph/init.ts
10045
- import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5 } from "fs";
10665
+ import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6 } from "fs";
10046
10666
  import { join as join18 } from "path";
10047
10667
  import { execSync as execSync6 } from "child_process";
10048
10668
  function graphInit() {
@@ -10054,9 +10674,9 @@ function graphInit() {
10054
10674
  }
10055
10675
  const m = read(root);
10056
10676
  const modelsDir = join18(root, "src", "models");
10057
- mkdirSync5(modelsDir, { recursive: true });
10677
+ mkdirSync6(modelsDir, { recursive: true });
10058
10678
  const indexPath = join18(modelsDir, "index.ts");
10059
- if (!existsSync14(indexPath)) {
10679
+ if (!existsSync15(indexPath)) {
10060
10680
  writeFileSync7(indexPath, `// Data models for ${m.name}
10061
10681
  // Generated by construct graph init
10062
10682
 
@@ -10065,7 +10685,7 @@ function graphInit() {
10065
10685
  `);
10066
10686
  }
10067
10687
  const pkgPath = join18(root, "package.json");
10068
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
10688
+ const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
10069
10689
  if (!pkg.dependencies)
10070
10690
  pkg.dependencies = {};
10071
10691
  if (!pkg.dependencies["@construct-space/graph"]) {
@@ -10095,7 +10715,7 @@ function graphInit() {
10095
10715
  }
10096
10716
 
10097
10717
  // src/commands/graph/generate.ts
10098
- import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
10718
+ import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7 } from "fs";
10099
10719
  import { join as join19 } from "path";
10100
10720
  var FIELD_TYPES = {
10101
10721
  string: "field.string()",
@@ -10249,9 +10869,9 @@ function generate2(modelName, fieldSpecs, options) {
10249
10869
  const content = lines.join(`
10250
10870
  `);
10251
10871
  const modelsDir = join19(root, "src", "models");
10252
- mkdirSync6(modelsDir, { recursive: true });
10872
+ mkdirSync7(modelsDir, { recursive: true });
10253
10873
  const filePath = join19(modelsDir, `${name}.ts`);
10254
- if (existsSync15(filePath)) {
10874
+ if (existsSync16(filePath)) {
10255
10875
  console.log(source_default.yellow(` Model file already exists: src/models/${name}.ts`));
10256
10876
  console.log(source_default.dim(" Overwriting..."));
10257
10877
  }
@@ -10270,8 +10890,8 @@ function generate2(modelName, fieldSpecs, options) {
10270
10890
  function updateBarrel(modelsDir, modelName) {
10271
10891
  const indexPath = join19(modelsDir, "index.ts");
10272
10892
  const exportLine = `export { ${modelName} } from './${modelName}'`;
10273
- if (existsSync15(indexPath)) {
10274
- const content = readFileSync11(indexPath, "utf-8");
10893
+ if (existsSync16(indexPath)) {
10894
+ const content = readFileSync12(indexPath, "utf-8");
10275
10895
  if (content.includes(exportLine))
10276
10896
  return;
10277
10897
  writeFileSync8(indexPath, content.trimEnd() + `
@@ -10285,7 +10905,7 @@ function updateBarrel(modelsDir, modelName) {
10285
10905
  }
10286
10906
 
10287
10907
  // src/commands/graph/push.ts
10288
- import { existsSync as existsSync16, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "fs";
10908
+ import { existsSync as existsSync17, readdirSync as readdirSync4, readFileSync as readFileSync13 } from "fs";
10289
10909
  import { join as join20, basename as basename7 } from "path";
10290
10910
  async function graphPush() {
10291
10911
  const root = process.cwd();
@@ -10295,7 +10915,7 @@ async function graphPush() {
10295
10915
  }
10296
10916
  const m = read(root);
10297
10917
  const modelsDir = join20(root, "src", "models");
10298
- if (!existsSync16(modelsDir)) {
10918
+ if (!existsSync17(modelsDir)) {
10299
10919
  console.error(source_default.red("No src/models/ directory found. Run 'construct graph init' first."));
10300
10920
  process.exit(1);
10301
10921
  }
@@ -10308,7 +10928,7 @@ async function graphPush() {
10308
10928
  console.log(source_default.blue(`Pushing ${modelFiles.length} model(s) for space: ${m.id}`));
10309
10929
  const models = [];
10310
10930
  for (const file of modelFiles) {
10311
- const content = readFileSync12(join20(modelsDir, file), "utf-8");
10931
+ const content = readFileSync13(join20(modelsDir, file), "utf-8");
10312
10932
  const model = parseModelFile(content, basename7(file, ".ts"));
10313
10933
  if (model)
10314
10934
  models.push(model);
@@ -10424,7 +11044,7 @@ function parseModelFile(content, fileName) {
10424
11044
  }
10425
11045
 
10426
11046
  // src/commands/graph/migrate.ts
10427
- import { existsSync as existsSync17, readdirSync as readdirSync5, readFileSync as readFileSync13 } from "fs";
11047
+ import { existsSync as existsSync18, readdirSync as readdirSync5, readFileSync as readFileSync14 } from "fs";
10428
11048
  import { join as join21, basename as basename8 } from "path";
10429
11049
  async function graphMigrate(options) {
10430
11050
  const root = process.cwd();
@@ -10434,7 +11054,7 @@ async function graphMigrate(options) {
10434
11054
  }
10435
11055
  const m = read(root);
10436
11056
  const modelsDir = join21(root, "src", "models");
10437
- if (!existsSync17(modelsDir)) {
11057
+ if (!existsSync18(modelsDir)) {
10438
11058
  console.error(source_default.red("No src/models/ directory. Run 'construct graph init' first."));
10439
11059
  process.exit(1);
10440
11060
  }
@@ -10464,7 +11084,7 @@ async function graphMigrate(options) {
10464
11084
  const modelFiles = readdirSync5(modelsDir).filter((f) => f.endsWith(".ts") && f !== "index.ts");
10465
11085
  const localModels = [];
10466
11086
  for (const file of modelFiles) {
10467
- const content = readFileSync13(join21(modelsDir, file), "utf-8");
11087
+ const content = readFileSync14(join21(modelsDir, file), "utf-8");
10468
11088
  const model = parseModelFields(content, basename8(file, ".ts"));
10469
11089
  if (model)
10470
11090
  localModels.push(model);
@@ -10568,7 +11188,7 @@ function parseModelFields(content, fileName) {
10568
11188
  }
10569
11189
 
10570
11190
  // src/index.ts
10571
- var VERSION = "1.1.11";
11191
+ var VERSION = "1.1.12";
10572
11192
  var program2 = new Command;
10573
11193
  program2.name("construct").description("Construct CLI \u2014 scaffold, build, develop, and publish spaces").version(VERSION);
10574
11194
  program2.command("scaffold [name]").alias("new").alias("create").description("Create a new Construct space project").option("--with-tests", "Include E2E testing boilerplate").option("--full", "Full preset: multiple pages, extra skills, widget templates").action(async (name, opts) => scaffold(name, opts));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@construct-space/cli",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "Construct CLI — scaffold, build, develop, and publish spaces",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "templates"
17
17
  ],
18
18
  "scripts": {
19
- "build": "bun build src/index.ts --outdir dist --target bun --format esm && cp -r templates dist/",
19
+ "build": "bun scripts/embed-templates.ts && bun build src/index.ts --outdir dist --target bun --format esm && cp -r templates dist/",
20
20
  "dev": "bun run src/index.ts",
21
21
  "test": "bun test",
22
22
  "typecheck": "tsc --noEmit"