reset-framework-cli 1.1.4 → 1.2.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.
package/README.md CHANGED
@@ -16,32 +16,42 @@ npm install -g reset-framework-cli
16
16
  - `reset-framework-cli package`
17
17
  - `reset-framework-cli doctor`
18
18
 
19
- ## Package boundary
20
-
21
- - `reset-framework-cli` orchestrates the framework.
22
- - `@reset-framework/native` provides the CMake-based runtime source package.
23
- - `@reset-framework/sdk` provides the frontend bridge package.
24
- - `@reset-framework/schema` provides the config schema package.
25
-
26
- ## How it works
27
-
28
- - `reset-framework-cli dev` and `reset-framework-cli build` compile the native runtime into an app-local cache under `.reset/framework`.
29
- - The generated desktop app is assembled under `.reset/build`.
30
- - On first native build, the CLI will reuse an existing vcpkg toolchain when available, or bootstrap one into `~/.reset-framework-cli/vcpkg`.
31
- - The CLI remains thin. Native platform logic lives in the native package, not in command code.
32
-
33
- ## Requirements
34
-
35
- - Node.js `>= 20.19.0`
36
- - CMake
37
- - Ninja
38
- - Git
39
- - A native compiler toolchain for the target platform
40
-
41
- ## Publish model
42
-
43
- `reset-framework-cli` should be published only after:
44
-
45
- 1. `@reset-framework/schema`
46
- 2. `@reset-framework/sdk`
47
- 3. `@reset-framework/native`
19
+ ## Package boundary
20
+
21
+ - `reset-framework-cli` orchestrates the framework.
22
+ - `@reset-framework/runtime-*` provides the bundled runtime package for the current platform.
23
+ - `@reset-framework/native` provides the CMake-based runtime source package.
24
+ - `@reset-framework/sdk` provides the frontend bridge package.
25
+ - `@reset-framework/schema` provides the config schema package.
26
+
27
+ ## How it works
28
+
29
+ - `reset-framework-cli dev` and `reset-framework-cli build` use the bundled runtime package for the current platform by default.
30
+ - `reset-framework-cli dev --runtime-source` and `reset-framework-cli build --runtime-source` compile the runtime from `@reset-framework/native` into an app-local cache under `.reset/framework`.
31
+ - The generated desktop app is assembled under `.reset/build`.
32
+ - On first source build, the CLI will reuse an existing vcpkg toolchain when available, or bootstrap one into `~/.reset-framework-cli/vcpkg`.
33
+ - The CLI remains thin. Native platform logic lives in the native package, not in command code.
34
+
35
+ ## Requirements
36
+
37
+ - Node.js `>= 20.19.0`
38
+ - A bundled runtime package for the target platform
39
+
40
+ Source build requirements:
41
+
42
+ - `@reset-framework/native`
43
+ - CMake
44
+ - Ninja
45
+ - Git
46
+ - A native compiler toolchain for the target platform
47
+
48
+ ## Publish model
49
+
50
+ `reset-framework-cli` should be published only after:
51
+
52
+ 1. `@reset-framework/schema`
53
+ 2. `@reset-framework/sdk`
54
+ 3. `@reset-framework/runtime-darwin-arm64`
55
+ 4. `@reset-framework/runtime-darwin-x64`
56
+ 5. `@reset-framework/runtime-win32-x64`
57
+ 6. `@reset-framework/native`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reset-framework-cli",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Command-line tooling for Reset Framework.",
6
6
  "license": "MIT",
@@ -11,9 +11,13 @@
11
11
  "node": ">=20.19.0"
12
12
  },
13
13
  "dependencies": {
14
- "@reset-framework/native": "1.1.4",
15
- "@reset-framework/schema": "1.1.4",
16
- "@reset-framework/sdk": "1.1.4"
14
+ "@reset-framework/schema": "1.2.0",
15
+ "@reset-framework/sdk": "1.2.0"
16
+ },
17
+ "optionalDependencies": {
18
+ "@reset-framework/runtime-darwin-arm64": "1.2.0",
19
+ "@reset-framework/runtime-darwin-x64": "1.2.0",
20
+ "@reset-framework/runtime-win32-x64": "1.2.0"
17
21
  },
18
22
  "bin": {
19
23
  "reset-framework-cli": "src/index.js"
@@ -1,5 +1,5 @@
1
- import { buildFrameworkRuntime } from "../lib/framework.js"
2
- import { stageMacOSAppBundle, stageWindowsAppBundle } from "../lib/output.js"
1
+ import { prepareFrameworkRuntime } from "../lib/framework.js"
2
+ import { stageMacOSAppBundle, stageWindowsAppBundle } from "../lib/output.js"
3
3
  import { resolvePackageManagerCommand, runCommand } from "../lib/process.js"
4
4
  import {
5
5
  assertAppProject,
@@ -8,11 +8,12 @@ import {
8
8
  resolveAppOutputPaths,
9
9
  resolveAppPaths,
10
10
  resolveAppPackageManager,
11
- resolveConfigPath,
12
- resolveFrontendDir,
13
- resolveFrameworkBuildPaths,
14
- resolveFrameworkPaths
15
- } from "../lib/project.js"
11
+ resolveConfigPath,
12
+ resolveFrontendDir,
13
+ resolveFrameworkBuildPaths,
14
+ resolveFrameworkRuntimeStrategy,
15
+ resolveFrameworkPaths
16
+ } from "../lib/project.js"
16
17
  import {
17
18
  createProgress,
18
19
  printBanner,
@@ -24,10 +25,11 @@ import {
24
25
  export const description = "Build the frontend, runtime, and final desktop app bundle"
25
26
 
26
27
  export async function run(context) {
27
- const dryRun = Boolean(context.flags["dry-run"])
28
- const skipFrontend = Boolean(context.flags["skip-frontend"])
29
- const skipRuntime = Boolean(context.flags["skip-runtime"])
30
- const skipStage = Boolean(context.flags["skip-stage"])
28
+ const dryRun = Boolean(context.flags["dry-run"])
29
+ const skipFrontend = Boolean(context.flags["skip-frontend"])
30
+ const skipRuntime = Boolean(context.flags["skip-runtime"])
31
+ const skipStage = Boolean(context.flags["skip-stage"])
32
+ const preferSource = Boolean(context.flags["runtime-source"])
31
33
 
32
34
  const appPaths = resolveAppPaths(context.projectRoot)
33
35
  const frameworkPaths = resolveFrameworkPaths()
@@ -36,32 +38,40 @@ export async function run(context) {
36
38
  const config = loadResetConfig(appPaths)
37
39
  assertAppProject(appPaths, config)
38
40
  const packageManager = resolveAppPackageManager(appPaths, config)
39
- const outputPaths = resolveAppOutputPaths(appPaths, config)
40
- const configPath = resolveConfigPath(appPaths)
41
- const frontendDir = resolveFrontendDir(appPaths, config)
42
- const frameworkBuildPaths = resolveFrameworkBuildPaths(appPaths)
43
- const steps = [
44
- !skipFrontend ? "Build frontend" : null,
45
- !skipRuntime ? "Build runtime" : null,
46
- !skipStage ? "Stage desktop bundle" : null
47
- ].filter(Boolean)
41
+ const outputPaths = resolveAppOutputPaths(appPaths, config)
42
+ const configPath = resolveConfigPath(appPaths)
43
+ const frontendDir = resolveFrontendDir(appPaths, config)
44
+ const frameworkBuildPaths = resolveFrameworkBuildPaths(appPaths)
45
+ const runtimeStrategy = resolveFrameworkRuntimeStrategy(frameworkPaths, { preferSource })
46
+ const steps = [
47
+ !skipFrontend ? "Build frontend" : null,
48
+ !skipRuntime ? "Prepare runtime" : null,
49
+ !skipStage ? "Stage desktop bundle" : null
50
+ ].filter(Boolean)
48
51
 
49
52
  printBanner("reset-framework-cli build", description)
50
53
  printSection("Project")
51
- printKeyValueTable([
52
- ["Config", configPath],
53
- ["Frontend", frontendDir],
54
- ["Package manager", packageManager],
55
- ["Output", outputPaths.appBundlePath]
56
- ])
54
+ printKeyValueTable([
55
+ ["Config", configPath],
56
+ ["Frontend", frontendDir],
57
+ ["Package manager", packageManager],
58
+ ["Output", outputPaths.appBundlePath],
59
+ ["Runtime", `${runtimeStrategy.kind === "prebuilt" ? "bundled" : "source"} (${runtimeStrategy.label})`]
60
+ ])
57
61
  console.log("")
58
62
 
59
- printSection("Plan")
60
- printStatusTable([
61
- [skipFrontend ? "skip" : "ready", "Frontend", skipFrontend ? "Skipping frontend build" : "Build static frontend assets"],
62
- [skipRuntime ? "skip" : "ready", "Runtime", skipRuntime ? "Skipping release runtime build" : "Configure and build the native runtime"],
63
- [skipStage ? "skip" : "ready", "Bundle", skipStage ? "Skipping app bundle staging" : "Assemble the final desktop app bundle"]
64
- ])
63
+ printSection("Plan")
64
+ printStatusTable([
65
+ [skipFrontend ? "skip" : "ready", "Frontend", skipFrontend ? "Skipping frontend build" : "Build static frontend assets"],
66
+ [
67
+ skipRuntime ? "skip" : "ready",
68
+ "Runtime",
69
+ skipRuntime
70
+ ? (runtimeStrategy.kind === "prebuilt" ? "Reuse the bundled runtime package" : "Skip the source runtime build")
71
+ : (runtimeStrategy.kind === "prebuilt" ? "Use the bundled runtime package" : "Configure and build the runtime from source")
72
+ ],
73
+ [skipStage ? "skip" : "ready", "Bundle", skipStage ? "Skipping app bundle staging" : "Assemble the final desktop app bundle"]
74
+ ])
65
75
 
66
76
  if (dryRun) {
67
77
  console.log("")
@@ -92,23 +102,25 @@ export async function run(context) {
92
102
  progress.tick("Frontend assets built")
93
103
  }
94
104
 
95
- if (!skipRuntime) {
96
- await buildFrameworkRuntime(frameworkPaths, frameworkBuildPaths, "release", {
97
- cwd: appPaths.appRoot,
98
- dryRun
99
- })
100
- progress.tick("Native runtime built")
101
- }
102
-
105
+ if (!skipRuntime) {
106
+ const preparedRuntime = await prepareFrameworkRuntime(frameworkPaths, frameworkBuildPaths, "release", {
107
+ cwd: appPaths.appRoot,
108
+ dryRun,
109
+ preferSource
110
+ })
111
+ progress.tick(preparedRuntime.kind === "prebuilt" ? "Bundled runtime ready" : "Native runtime built")
112
+ }
113
+
103
114
  if (!skipStage) {
104
115
  const stageBundle = process.platform === "win32" ? stageWindowsAppBundle : stageMacOSAppBundle
105
- await stageBundle(frameworkBuildPaths, appPaths, config, {
116
+ await stageBundle(frameworkPaths, frameworkBuildPaths, config, {
106
117
  dryRun,
107
118
  outputPaths,
108
- configPath
119
+ configPath,
120
+ preferSource
109
121
  })
110
- progress.tick("Desktop app bundle staged")
111
- }
122
+ progress.tick("Desktop app bundle staged")
123
+ }
112
124
 
113
125
  console.log("")
114
126
  printSection("Result")
@@ -1,4 +1,4 @@
1
- import { buildFrameworkRuntime } from "../lib/framework.js"
1
+ import { prepareFrameworkRuntime } from "../lib/framework.js"
2
2
  import {
3
3
  registerChildCleanup,
4
4
  resolvePackageManagerCommand,
@@ -17,6 +17,7 @@ import {
17
17
  resolveFrontendDir,
18
18
  resolveFrameworkBuildPaths,
19
19
  resolveFrameworkRuntimeBinary,
20
+ resolveFrameworkRuntimeStrategy,
20
21
  resolveFrameworkPaths
21
22
  } from "../lib/project.js"
22
23
  import {
@@ -30,10 +31,11 @@ import {
30
31
  export const description = "Run the frontend dev server and native host"
31
32
 
32
33
  export async function run(context) {
33
- const dryRun = Boolean(context.flags["dry-run"])
34
- const skipFrontend = Boolean(context.flags["skip-frontend"])
35
- const skipRuntime = Boolean(context.flags["skip-runtime"])
36
- const noOpen = Boolean(context.flags["no-open"])
34
+ const dryRun = Boolean(context.flags["dry-run"])
35
+ const skipFrontend = Boolean(context.flags["skip-frontend"])
36
+ const skipRuntime = Boolean(context.flags["skip-runtime"])
37
+ const noOpen = Boolean(context.flags["no-open"])
38
+ const preferSource = Boolean(context.flags["runtime-source"])
37
39
 
38
40
  const appPaths = resolveAppPaths(context.projectRoot)
39
41
  const frameworkPaths = resolveFrameworkPaths()
@@ -43,31 +45,39 @@ export async function run(context) {
43
45
  assertAppProject(appPaths, config)
44
46
  const packageManager = resolveAppPackageManager(appPaths, config)
45
47
  const devServer = resolveDevServerOptions(config)
46
- const configPath = resolveConfigPath(appPaths)
47
- const frontendDir = resolveFrontendDir(appPaths, config)
48
- const frameworkBuildPaths = resolveFrameworkBuildPaths(appPaths)
49
- const steps = [
50
- !skipRuntime ? "Build native runtime" : null,
51
- !skipFrontend ? "Start frontend dev server" : null,
52
- !noOpen ? "Launch desktop window" : null
53
- ].filter(Boolean)
48
+ const configPath = resolveConfigPath(appPaths)
49
+ const frontendDir = resolveFrontendDir(appPaths, config)
50
+ const frameworkBuildPaths = resolveFrameworkBuildPaths(appPaths)
51
+ const runtimeStrategy = resolveFrameworkRuntimeStrategy(frameworkPaths, { preferSource })
52
+ const steps = [
53
+ !skipRuntime ? "Prepare runtime" : null,
54
+ !skipFrontend ? "Start frontend dev server" : null,
55
+ !noOpen ? "Launch desktop window" : null
56
+ ].filter(Boolean)
54
57
 
55
58
  printBanner("reset-framework-cli dev", description)
56
59
  printSection("Project")
57
- printKeyValueTable([
58
- ["Config", configPath],
59
- ["Frontend", frontendDir],
60
- ["Package manager", packageManager],
61
- ["Dev URL", config.frontend.devUrl]
62
- ])
60
+ printKeyValueTable([
61
+ ["Config", configPath],
62
+ ["Frontend", frontendDir],
63
+ ["Package manager", packageManager],
64
+ ["Dev URL", config.frontend.devUrl],
65
+ ["Runtime", `${runtimeStrategy.kind === "prebuilt" ? "bundled" : "source"} (${runtimeStrategy.label})`]
66
+ ])
63
67
  console.log("")
64
68
 
65
- printSection("Plan")
66
- printStatusTable([
67
- [skipRuntime ? "skip" : "ready", "Runtime", skipRuntime ? "Reusing existing native dev build" : "Configure and build the native runtime"],
68
- [skipFrontend ? "skip" : "ready", "Frontend", skipFrontend ? "Expecting an already running dev server" : "Start the frontend dev server and wait for readiness"],
69
- [noOpen ? "skip" : "ready", "Window", noOpen ? "Do not launch the desktop window" : "Start the native host with the active project config"]
70
- ])
69
+ printSection("Plan")
70
+ printStatusTable([
71
+ [
72
+ skipRuntime ? "skip" : "ready",
73
+ "Runtime",
74
+ skipRuntime
75
+ ? (runtimeStrategy.kind === "prebuilt" ? "Reuse the bundled runtime package" : "Reuse the existing source runtime build")
76
+ : (runtimeStrategy.kind === "prebuilt" ? "Use the bundled runtime package" : "Configure and build the runtime from source")
77
+ ],
78
+ [skipFrontend ? "skip" : "ready", "Frontend", skipFrontend ? "Expecting an already running dev server" : "Start the frontend dev server and wait for readiness"],
79
+ [noOpen ? "skip" : "ready", "Window", noOpen ? "Do not launch the desktop window" : "Start the native host with the active project config"]
80
+ ])
71
81
 
72
82
  if (dryRun) {
73
83
  console.log("")
@@ -88,15 +98,16 @@ export async function run(context) {
88
98
  }
89
99
 
90
100
  console.log("")
91
- const progress = createProgress(steps.length, "Dev")
92
-
93
- if (!skipRuntime) {
94
- await buildFrameworkRuntime(frameworkPaths, frameworkBuildPaths, "dev", {
95
- cwd: appPaths.appRoot,
96
- dryRun
97
- })
98
- progress.tick("Native runtime built")
99
- }
101
+ const progress = createProgress(steps.length, "Dev")
102
+
103
+ if (!skipRuntime) {
104
+ const preparedRuntime = await prepareFrameworkRuntime(frameworkPaths, frameworkBuildPaths, "dev", {
105
+ cwd: appPaths.appRoot,
106
+ dryRun,
107
+ preferSource
108
+ })
109
+ progress.tick(preparedRuntime.kind === "prebuilt" ? "Bundled runtime ready" : "Native runtime built")
110
+ }
100
111
 
101
112
  const children = []
102
113
 
@@ -123,13 +134,14 @@ export async function run(context) {
123
134
  }
124
135
 
125
136
  if (!noOpen) {
126
- const appBinary = resolveFrameworkRuntimeBinary(frameworkBuildPaths, "dev", {
127
- mustExist: !dryRun
137
+ const appBinary = resolveFrameworkRuntimeBinary(frameworkPaths, frameworkBuildPaths, "dev", {
138
+ mustExist: !dryRun,
139
+ strategy: runtimeStrategy
128
140
  })
129
141
  const appProcess = spawnCommand(appBinary, [], {
130
- cwd: appPaths.appRoot,
131
- env: {
132
- RESET_CONFIG_PATH: configPath,
142
+ cwd: appPaths.appRoot,
143
+ env: {
144
+ RESET_CONFIG_PATH: configPath,
133
145
  RESET_FRONTEND_DEV_URL: config.frontend.devUrl
134
146
  },
135
147
  dryRun
@@ -162,6 +174,6 @@ export async function run(context) {
162
174
  )
163
175
  ])
164
176
  } finally {
165
- cleanup()
177
+ await cleanup()
166
178
  }
167
179
  }
@@ -1,11 +1,14 @@
1
1
  import { existsSync } from "node:fs"
2
2
 
3
- import {
4
- getAppChecks,
5
- getFrameworkChecks,
6
- loadResetConfig,
7
- resolveFrontendDir,
8
- resolveAppPaths,
3
+ import {
4
+ getAppChecks,
5
+ getFrameworkChecks,
6
+ getFrameworkRuntimeChecks,
7
+ getFrameworkRuntimeModeSummary,
8
+ hasFrameworkSourcePackage,
9
+ loadResetConfig,
10
+ resolveFrontendDir,
11
+ resolveAppPaths,
9
12
  resolveConfigPath,
10
13
  resolveFrameworkPaths
11
14
  } from "../lib/project.js"
@@ -19,15 +22,23 @@ import {
19
22
 
20
23
  export const description = "Inspect the current project layout"
21
24
 
22
- export async function run(context) {
23
- const appPaths = resolveAppPaths(context.projectRoot)
24
- const frameworkPaths = resolveFrameworkPaths()
25
-
26
- let config = null
27
-
28
- if (existsSync(resolveConfigPath(appPaths))) {
29
- config = loadResetConfig(appPaths)
30
- }
25
+ export async function run(context) {
26
+ const appPaths = resolveAppPaths(context.projectRoot)
27
+ const frameworkPaths = resolveFrameworkPaths()
28
+ let runtimeMode = null
29
+ let runtimeModeError = null
30
+
31
+ let config = null
32
+
33
+ if (existsSync(resolveConfigPath(appPaths))) {
34
+ config = loadResetConfig(appPaths)
35
+ }
36
+
37
+ try {
38
+ runtimeMode = getFrameworkRuntimeModeSummary(frameworkPaths)
39
+ } catch (error) {
40
+ runtimeModeError = error instanceof Error ? error.message : String(error)
41
+ }
31
42
 
32
43
  printBanner("reset-framework-cli doctor", description)
33
44
 
@@ -49,31 +60,68 @@ export async function run(context) {
49
60
  console.log("")
50
61
  printSection("Framework installation")
51
62
 
52
- printStatusTable(
53
- getFrameworkChecks(frameworkPaths).map(([label, filePath]) => [
54
- existsSync(filePath) ? "ok" : "missing",
63
+ printStatusTable(
64
+ getFrameworkChecks(frameworkPaths).map(([label, filePath]) => [
65
+ existsSync(filePath) ? "ok" : "missing",
55
66
  label,
56
67
  filePath
57
68
  ])
58
69
  )
59
70
 
60
- console.log("")
61
- printSection("Framework packages")
62
- printKeyValueTable([
63
- ["Native", `${frameworkPaths.frameworkPackage.packageName}@${frameworkPaths.frameworkPackage.version}`],
64
- ["SDK", `${frameworkPaths.sdkPackage.packageName}@${frameworkPaths.sdkPackage.version}`],
65
- ["Schema", `${frameworkPaths.schemaPackage.packageName}@${frameworkPaths.schemaPackage.version}`]
66
- ])
67
-
68
- console.log("")
69
- printSection("Native toolchain")
70
- const vcpkgToolchainFile = findVcpkgToolchainFile()
71
- printStatusTable([
72
- [vcpkgToolchainFile ? "ok" : "warn", "Framework source", frameworkPaths.frameworkRoot],
73
- [vcpkgToolchainFile ? "ok" : "warn", "vcpkg toolchain", vcpkgToolchainFile ?? "Will be bootstrapped on first native build"]
74
- ])
75
-
76
- if (config) {
71
+ console.log("")
72
+ printSection("Runtime installation")
73
+
74
+ const runtimeChecks = getFrameworkRuntimeChecks(frameworkPaths)
75
+ printStatusTable(
76
+ runtimeChecks.length > 0
77
+ ? runtimeChecks.map(([label, filePath]) => [
78
+ existsSync(filePath) ? "ok" : "missing",
79
+ label,
80
+ filePath
81
+ ])
82
+ : [["warn", "runtime", `No packaged runtime registered for ${process.platform}-${process.arch}`]]
83
+ )
84
+
85
+ console.log("")
86
+ printSection("Framework packages")
87
+ printKeyValueTable([
88
+ [
89
+ "Runtime",
90
+ frameworkPaths.runtimePackage?.packageInfo
91
+ ? `${frameworkPaths.runtimePackage.packageInfo.packageName}@${frameworkPaths.runtimePackage.packageInfo.version}`
92
+ : `Not installed for ${process.platform}-${process.arch}`
93
+ ],
94
+ [
95
+ "Native source",
96
+ frameworkPaths.frameworkPackage
97
+ ? `${frameworkPaths.frameworkPackage.packageName}@${frameworkPaths.frameworkPackage.version}`
98
+ : "Not installed"
99
+ ],
100
+ ["SDK", `${frameworkPaths.sdkPackage.packageName}@${frameworkPaths.sdkPackage.version}`],
101
+ ["Schema", `${frameworkPaths.schemaPackage.packageName}@${frameworkPaths.schemaPackage.version}`]
102
+ ])
103
+
104
+ console.log("")
105
+ printSection("Runtime mode")
106
+ printStatusTable([
107
+ [
108
+ runtimeMode ? "ok" : "warn",
109
+ "Runtime mode",
110
+ runtimeMode ? `${runtimeMode.kind} (${runtimeMode.label})` : runtimeModeError
111
+ ]
112
+ ])
113
+
114
+ if (hasFrameworkSourcePackage(frameworkPaths)) {
115
+ console.log("")
116
+ printSection("Native toolchain")
117
+ const vcpkgToolchainFile = findVcpkgToolchainFile()
118
+ printStatusTable([
119
+ ["ok", "Framework source", frameworkPaths.frameworkRoot],
120
+ [vcpkgToolchainFile ? "ok" : "warn", "vcpkg toolchain", vcpkgToolchainFile ?? "Will be bootstrapped on first source build"]
121
+ ])
122
+ }
123
+
124
+ if (config) {
77
125
  console.log("")
78
126
  printSection("Config")
79
127
  printKeyValueTable([