@highstate/cli 0.9.20 → 0.9.21

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "sourceHashes": {
3
- "./dist/main.js": 1533043521
3
+ "./dist/main.js": 2872049114
4
4
  }
5
5
  }
@@ -1,7 +1,7 @@
1
1
  import { int32ToBytes } from './chunk-CMECLVT7.js';
2
2
  import console from 'node:console';
3
- import { isComponent, isEntity, isUnitModel } from '@highstate/contract';
4
3
  import { Crc32, crc32 } from '@aws-crypto/crc32';
4
+ import { isComponent, isEntity, isUnitModel } from '@highstate/contract';
5
5
  import { encode } from '@msgpack/msgpack';
6
6
 
7
7
  async function loadLibrary(logger, modulePaths) {
@@ -79,5 +79,5 @@ function calculateEntityDefinitionHash(entity) {
79
79
  }
80
80
 
81
81
  export { loadLibrary };
82
- //# sourceMappingURL=library-loader-6TJTW2HX.js.map
83
- //# sourceMappingURL=library-loader-6TJTW2HX.js.map
82
+ //# sourceMappingURL=library-loader-PZWYMBAE.js.map
83
+ //# sourceMappingURL=library-loader-PZWYMBAE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/library-loader.ts"],"names":[],"mappings":"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","file":"library-loader-6TJTW2HX.js","sourcesContent":["import type { Logger } from \"pino\"\nimport console from \"node:console\"\nimport {\n type Component,\n type ComponentModel,\n type Entity,\n type EntityModel,\n isComponent,\n isEntity,\n isUnitModel,\n} from \"@highstate/contract\"\nimport { Crc32, crc32 } from \"@aws-crypto/crc32\"\nimport { encode } from \"@msgpack/msgpack\"\nimport { int32ToBytes } from \"./utils\"\n\nexport type Library = Readonly<{\n components: Readonly<Record<string, ComponentModel>>\n entities: Readonly<Record<string, EntityModel>>\n}>\n\nexport async function loadLibrary(logger: Logger, modulePaths: string[]): Promise<Library> {\n const modules: Record<string, unknown> = {}\n for (const modulePath of modulePaths) {\n try {\n logger.debug({ modulePath }, \"loading module\")\n modules[modulePath] = await import(modulePath)\n\n logger.debug({ modulePath }, \"module loaded\")\n } catch (error) {\n console.error(error)\n\n throw new Error(`Failed to load module \"${modulePath}\"`, { cause: error })\n }\n }\n\n const components: Record<string, ComponentModel> = {}\n const entities: Record<string, EntityModel> = {}\n\n await _loadLibrary(modules, components, entities)\n\n logger.info(\n {\n componentCount: Object.keys(components).length,\n entityCount: Object.keys(entities).length,\n },\n \"library loaded\",\n )\n\n logger.trace({ components, entities }, \"library content\")\n\n return { components, entities }\n}\n\nasync function _loadLibrary(\n value: unknown,\n components: Record<string, ComponentModel>,\n entities: Record<string, EntityModel>,\n): Promise<void> {\n if (isComponent(value)) {\n const entityHashes: number[] = []\n for (const entity of value.entities.values()) {\n entity.model.definitionHash ??= calculateEntityDefinitionHash(entity)\n entityHashes.push(entity.model.definitionHash)\n }\n\n components[value.model.type] = value.model\n value.model.definitionHash = await calculateComponentDefinitionHash(value, entityHashes)\n\n return\n }\n\n if (isEntity(value)) {\n entities[value.type] = value.model\n entities[value.type].definitionHash ??= calculateEntityDefinitionHash(value)\n\n // @ts-expect-error remove the schema since it's not needed in the designer\n delete value.model.schema\n return\n }\n\n if (typeof value !== \"object\" || value === null) {\n return\n }\n\n if (\"_zod\" in value) {\n // this is a zod schema, we can skip it\n return\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n await _loadLibrary(item, components, entities)\n }\n\n return\n }\n\n for (const key in value) {\n await _loadLibrary((value as Record<string, unknown>)[key], components, entities)\n }\n}\n\nasync function calculateComponentDefinitionHash(\n component: Component,\n entityHashes: number[],\n): Promise<number> {\n const result = new Crc32()\n\n // 1. include the full component model\n result.update(encode(component.model))\n\n if (!isUnitModel(component.model)) {\n // 2. for composite components, include the content of the serialized create function\n // const serializedCreate = await serializeFunction(component[originalCreate])\n const serializedCreate = { text: \"TODO: investigate why serializeFunction hangs\" }\n result.update(Buffer.from(serializedCreate.text))\n }\n\n // 3. include the hashes of all entities\n for (const entityHash of entityHashes) {\n result.update(int32ToBytes(entityHash))\n }\n\n return result.digest()\n}\n\nfunction calculateEntityDefinitionHash(entity: Entity): number {\n return crc32(encode(entity.model))\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/library-loader.ts"],"names":[],"mappings":"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","file":"library-loader-PZWYMBAE.js","sourcesContent":["import type { Logger } from \"pino\"\nimport console from \"node:console\"\nimport { Crc32, crc32 } from \"@aws-crypto/crc32\"\nimport {\n type Component,\n type ComponentModel,\n type Entity,\n type EntityModel,\n isComponent,\n isEntity,\n isUnitModel,\n} from \"@highstate/contract\"\nimport { encode } from \"@msgpack/msgpack\"\nimport { int32ToBytes } from \"./utils\"\n\nexport type Library = Readonly<{\n components: Readonly<Record<string, ComponentModel>>\n entities: Readonly<Record<string, EntityModel>>\n}>\n\nexport async function loadLibrary(logger: Logger, modulePaths: string[]): Promise<Library> {\n const modules: Record<string, unknown> = {}\n for (const modulePath of modulePaths) {\n try {\n logger.debug({ modulePath }, \"loading module\")\n modules[modulePath] = await import(modulePath)\n\n logger.debug({ modulePath }, \"module loaded\")\n } catch (error) {\n console.error(error)\n\n throw new Error(`Failed to load module \"${modulePath}\"`, { cause: error })\n }\n }\n\n const components: Record<string, ComponentModel> = {}\n const entities: Record<string, EntityModel> = {}\n\n await _loadLibrary(modules, components, entities)\n\n logger.info(\n {\n componentCount: Object.keys(components).length,\n entityCount: Object.keys(entities).length,\n },\n \"library loaded\",\n )\n\n logger.trace({ components, entities }, \"library content\")\n\n return { components, entities }\n}\n\nasync function _loadLibrary(\n value: unknown,\n components: Record<string, ComponentModel>,\n entities: Record<string, EntityModel>,\n): Promise<void> {\n if (isComponent(value)) {\n const entityHashes: number[] = []\n for (const entity of value.entities.values()) {\n entity.model.definitionHash ??= calculateEntityDefinitionHash(entity)\n entityHashes.push(entity.model.definitionHash)\n }\n\n components[value.model.type] = value.model\n value.model.definitionHash = await calculateComponentDefinitionHash(value, entityHashes)\n\n return\n }\n\n if (isEntity(value)) {\n entities[value.type] = value.model\n entities[value.type].definitionHash ??= calculateEntityDefinitionHash(value)\n\n // @ts-expect-error remove the schema since it's not needed in the designer\n delete value.model.schema\n return\n }\n\n if (typeof value !== \"object\" || value === null) {\n return\n }\n\n if (\"_zod\" in value) {\n // this is a zod schema, we can skip it\n return\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n await _loadLibrary(item, components, entities)\n }\n\n return\n }\n\n for (const key in value) {\n await _loadLibrary((value as Record<string, unknown>)[key], components, entities)\n }\n}\n\nasync function calculateComponentDefinitionHash(\n component: Component,\n entityHashes: number[],\n): Promise<number> {\n const result = new Crc32()\n\n // 1. include the full component model\n result.update(encode(component.model))\n\n if (!isUnitModel(component.model)) {\n // 2. for composite components, include the content of the serialized create function\n // const serializedCreate = await serializeFunction(component[originalCreate])\n const serializedCreate = { text: \"TODO: investigate why serializeFunction hangs\" }\n result.update(Buffer.from(serializedCreate.text))\n }\n\n // 3. include the hashes of all entities\n for (const entityHash of entityHashes) {\n result.update(int32ToBytes(entityHash))\n }\n\n return result.digest()\n}\n\nfunction calculateEntityDefinitionHash(entity: Entity): number {\n return crc32(encode(entity.model))\n}\n"]}
package/dist/main.js CHANGED
@@ -1,27 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import { int32ToBytes } from './chunk-CMECLVT7.js';
3
- import { Command, UsageError, Option, Cli, Builtins } from 'clipanion';
4
- import { readPackageJSON, resolvePackageJSON } from 'pkg-types';
5
- import { addDevDependency } from 'nypm';
6
- import { LogLevels, consola } from 'consola';
7
- import { colorize } from 'consola/utils';
8
- import { getPort } from 'get-port-please';
3
+ import { Command, Option, UsageError, Cli, Builtins } from 'clipanion';
4
+ import { identityToRecipient } from 'age-encryption';
5
+ import { writeFile, rm, readFile, mkdir, readdir } from 'node:fs/promises';
9
6
  import { PassThrough } from 'node:stream';
7
+ import { LogLevels, consola } from 'consola';
10
8
  import pino, { levels } from 'pino';
11
- import { writeFile, rm, readFile, mkdir, readdir } from 'node:fs/promises';
9
+ import MagicString from 'magic-string';
12
10
  import { parseAsync } from 'oxc-parser';
13
11
  import { walk } from 'oxc-walker';
14
- import MagicString from 'magic-string';
12
+ import { z } from 'zod';
15
13
  import { resolve, dirname, relative, join } from 'node:path';
16
14
  import { pathToFileURL, fileURLToPath } from 'node:url';
17
15
  import { crc32 } from '@aws-crypto/crc32';
18
16
  import { resolve as resolve$1 } from 'import-meta-resolve';
19
- import { z } from 'zod';
17
+ import { readPackageJSON, resolvePackageJSON } from 'pkg-types';
20
18
  import { existsSync } from 'node:fs';
21
- import { pipe, mapValues, mapKeys } from 'remeda';
22
- import { build } from 'tsup';
23
19
  import { encode } from '@msgpack/msgpack';
24
- import { identityToRecipient } from 'age-encryption';
20
+ import { mapValues } from 'remeda';
21
+ import { build } from 'tsup';
22
+ import { colorize } from 'consola/utils';
23
+ import { getPort } from 'get-port-please';
24
+ import { addDevDependency } from 'nypm';
25
25
 
26
26
  // package.json
27
27
  var version = "0.9.19";
@@ -66,20 +66,107 @@ function createConsolaStream() {
66
66
  return stream;
67
67
  }
68
68
 
69
- // src/shared/services.ts
70
- var services;
71
- function getBackendServices() {
72
- if (services) {
73
- return services;
69
+ // src/shared/bin-transformer.ts
70
+ function createBinTransformerPlugin(sourceFilePaths) {
71
+ const filter = new RegExp(`(${sourceFilePaths.join("|")})$`);
72
+ logger.debug("created bin transformer plugin with filter: %s", filter);
73
+ return {
74
+ name: "bin-transformer",
75
+ setup(build2) {
76
+ build2.onLoad({ filter }, async (args) => {
77
+ const content = await readFile(args.path, "utf-8");
78
+ return {
79
+ contents: `#!/usr/bin/env node
80
+
81
+ ${content}`,
82
+ loader: "ts"
83
+ };
84
+ });
85
+ }
86
+ };
87
+ }
88
+
89
+ // src/shared/entry-points.ts
90
+ function extractEntryPoints(packageJson) {
91
+ const exports = packageJson.exports;
92
+ let bin = packageJson.bin;
93
+ if (!exports && !bin) {
94
+ logger.warn("no exports or bin found in package.json");
95
+ return {};
74
96
  }
75
- services = import('@highstate/backend').then(({ getSharedServices }) => {
76
- return getSharedServices({
77
- services: {
78
- logger: logger.child({}, { msgPrefix: "[backend] " })
97
+ if (exports !== void 0 && (typeof exports !== "object" || Array.isArray(exports))) {
98
+ throw new Error("Exports field in package.json must be an object");
99
+ }
100
+ if (bin !== void 0 && typeof bin !== "object") {
101
+ if (!packageJson.name) {
102
+ throw new Error("Package name is required when bin is a string");
103
+ }
104
+ bin = { [packageJson.name]: bin };
105
+ }
106
+ const result = {};
107
+ if (exports) {
108
+ for (const [key, value] of Object.entries(exports)) {
109
+ let distPath;
110
+ if (typeof value === "string") {
111
+ distPath = value;
112
+ } else if (typeof value === "object" && !Array.isArray(value)) {
113
+ if (!value.default) {
114
+ throw new Error(`Export "${key}" must have a default field in package.json`);
115
+ }
116
+ if (typeof value.default !== "string") {
117
+ throw new Error(`Export "${key}" default field must be a string in package.json`);
118
+ }
119
+ distPath = value.default;
120
+ } else {
121
+ throw new Error(`Export "${key}" must be a string or an object in package.json`);
79
122
  }
80
- });
81
- });
82
- return services;
123
+ if (!distPath.startsWith("./dist/")) {
124
+ throw new Error(
125
+ `The default value of export "${key}" must start with "./dist/" in package.json, got "${distPath}"`
126
+ );
127
+ }
128
+ if (!distPath.endsWith(".js")) {
129
+ throw new Error(
130
+ `The default value of export "${key}" must end with ".js" in package.json, got "${distPath}"`
131
+ );
132
+ }
133
+ const targetName = distPath.slice(7).slice(0, -3);
134
+ result[targetName] = {
135
+ entryPoint: `./src/${targetName}.ts`,
136
+ targetName,
137
+ distPath,
138
+ isBin: false,
139
+ key
140
+ };
141
+ }
142
+ }
143
+ if (bin) {
144
+ for (const [key, value] of Object.entries(bin)) {
145
+ if (typeof value !== "string") {
146
+ throw new Error(`Bin entry "${key}" must be a string in package.json`);
147
+ }
148
+ const distPath = value;
149
+ if (!distPath.startsWith("./dist/")) {
150
+ throw new Error(
151
+ `The value of bin entry "${key}" must start with "./dist/" in package.json, got "${distPath}"`
152
+ );
153
+ }
154
+ if (!distPath.endsWith(".js")) {
155
+ throw new Error(
156
+ `The value of bin entry "${key}" must end with ".js" in package.json, got "${distPath}"`
157
+ );
158
+ }
159
+ const targetName = distPath.slice(7).slice(0, -3);
160
+ result[targetName] = {
161
+ entryPoint: `./src/${targetName}.ts`,
162
+ targetName,
163
+ distPath,
164
+ isBin: true,
165
+ key
166
+ };
167
+ }
168
+ }
169
+ return result;
83
170
  }
84
171
  var schemaTransformerPlugin = {
85
172
  name: "schema-transformer",
@@ -343,7 +430,21 @@ var highstateManifestSchema = z.object({
343
430
  sourceHashes: z.record(z.string(), z.number()).optional()
344
431
  });
345
432
 
346
- // src/shared/source-hash-calculator.ts
433
+ // src/shared/services.ts
434
+ var services;
435
+ function getBackendServices() {
436
+ if (services) {
437
+ return services;
438
+ }
439
+ services = import('@highstate/backend').then(({ getSharedServices }) => {
440
+ return getSharedServices({
441
+ services: {
442
+ logger: logger.child({}, { msgPrefix: "[backend] " })
443
+ }
444
+ });
445
+ });
446
+ return services;
447
+ }
347
448
  var SourceHashCalculator = class {
348
449
  constructor(packageJsonPath, packageJson, logger2) {
349
450
  this.packageJsonPath = packageJsonPath;
@@ -566,24 +667,6 @@ var SourceHashCalculator = class {
566
667
  return dependencies;
567
668
  }
568
669
  };
569
- function createBinTransformerPlugin(sourceFilePaths) {
570
- const filter = new RegExp(`(${sourceFilePaths.join("|")})$`);
571
- logger.debug("created bin transformer plugin with filter: %s", filter);
572
- return {
573
- name: "bin-transformer",
574
- setup(build2) {
575
- build2.onLoad({ filter }, async (args) => {
576
- const content = await readFile(args.path, "utf-8");
577
- return {
578
- contents: `#!/usr/bin/env node
579
-
580
- ${content}`,
581
- loader: "ts"
582
- };
583
- });
584
- }
585
- };
586
- }
587
670
  var packageJsonSchema = z.object({
588
671
  name: z.string(),
589
672
  highstate: highstateConfigSchema.optional()
@@ -709,14 +792,6 @@ async function createPackage(workspaceRoot, name, type) {
709
792
  await writeFile(
710
793
  join(packagePath, "tsconfig.json"),
711
794
  `${JSON.stringify(tsconfigContent, null, 2)}
712
- `,
713
- "utf-8"
714
- );
715
- await writeFile(
716
- join(packagePath, "CHANGELOG.md"),
717
- `# Changelog
718
-
719
- All notable changes to this project will be documented in this file.
720
795
  `,
721
796
  "utf-8"
722
797
  );
@@ -730,55 +805,20 @@ All notable changes to this project will be documented in this file.
730
805
  };
731
806
  }
732
807
 
733
- // src/commands/designer.ts
734
- var DesignerCommand = class extends Command {
735
- static paths = [["designer"]];
808
+ // src/commands/backend/identity.ts
809
+ var BackendIdentityCommand = class extends Command {
810
+ static paths = [["backend", "identity"]];
736
811
  static usage = Command.Usage({
737
- category: "Designer",
738
- description: "Starts the Highstate designer in the current project."
812
+ category: "Backend",
813
+ description: "Ensures the backend identity is set up and returns the recipient."
739
814
  });
740
815
  async execute() {
741
- const packageJson = await readPackageJSON();
742
- if (!packageJson.devDependencies?.["@highstate/cli"]) {
743
- throw new UsageError(
744
- "This project is not a Highstate project.\n@highstate/cli must be installed as a devDependency."
745
- );
746
- }
747
- if (!packageJson.devDependencies?.["@highstate/designer"]) {
748
- logger.info("Installing @highstate/designer...");
749
- await addDevDependency(["@highstate/designer", "classic-level"]);
750
- }
751
- logger.info("starting highstate designer...");
752
- await getBackendServices();
753
- const oldConsoleLog = console.log;
754
- const port = await getPort();
755
- process.env.NITRO_PORT = port.toString();
756
- process.env.NITRO_HOST = "0.0.0.0";
757
- await new Promise((resolve4) => {
758
- console.log = (message) => {
759
- if (message.startsWith("Listening on")) {
760
- resolve4();
761
- }
762
- };
763
- const path = "@highstate/designer/.output/server/index.mjs";
764
- void import(path);
765
- });
766
- console.log = oldConsoleLog;
767
- consola.log(
768
- [
769
- "\n ",
770
- colorize("bold", colorize("cyanBright", "Highstate Designer")),
771
- "\n ",
772
- colorize("greenBright", "\u279C Local: "),
773
- colorize("underline", colorize("cyanBright", `http://localhost:${port}`)),
774
- "\n"
775
- ].join("")
776
- );
777
- process.on("SIGINT", () => {
778
- process.stdout.write("\r");
779
- consola.info("shutting down highstate designer...");
780
- setTimeout(() => process.exit(0), 1e3);
781
- });
816
+ const backendLogger = logger.child({}, { msgPrefix: "[backend] " });
817
+ const { getOrCreateBackendIdentity } = await import('@highstate/backend');
818
+ const backendIdentity = await getOrCreateBackendIdentity(backendLogger);
819
+ const recipient = await identityToRecipient(backendIdentity);
820
+ logger.info(`stored backend identity is: ${recipient}`);
821
+ logger.info(`run "highstate backend unlock-method add ${recipient}" on other authorized device`);
782
822
  }
783
823
  };
784
824
  var BuildCommand = class extends Command {
@@ -800,64 +840,15 @@ var BuildCommand = class extends Command {
800
840
  if (highstateConfig.type === "worker") {
801
841
  this.noSourceHash = true;
802
842
  }
803
- const exports = packageJson.exports;
804
- let bin = packageJson.bin;
805
843
  if (!packageJson.name) {
806
844
  throw new Error("package.json must have a name field");
807
845
  }
808
- if (!exports && !bin) {
809
- logger.warn("no exports or bin found in package.json");
846
+ const entryPoints = extractEntryPoints(packageJson);
847
+ if (Object.keys(entryPoints).length === 0) {
810
848
  return;
811
849
  }
812
- if (exports !== void 0 && (typeof exports !== "object" || Array.isArray(exports))) {
813
- throw new Error("Exports field in package.json must be an object");
814
- }
815
- if (bin !== void 0 && typeof bin !== "object") {
816
- bin = { [packageJson.name]: bin };
817
- }
818
- const entry = pipe(
819
- {
820
- ...mapValues(exports ?? {}, (value) => ({ value, isBin: false })),
821
- ...mapValues(bin ?? {}, (value) => ({ value, isBin: true }))
822
- },
823
- mapValues(({ value, isBin }, key) => {
824
- let distPath;
825
- if (typeof value === "string") {
826
- distPath = value;
827
- } else if (typeof value === "object" && !Array.isArray(value)) {
828
- if (!value.default) {
829
- throw new Error(`Export "${key}" must have a default field in package.json`);
830
- }
831
- if (typeof value.default !== "string") {
832
- throw new Error(`Export "${key}" default field must be a string in package.json`);
833
- }
834
- distPath = value.default;
835
- } else {
836
- throw new Error(`Export "${key}" must be a string or an object in package.json`);
837
- }
838
- if (!distPath.startsWith("./dist/")) {
839
- throw new Error(
840
- `The default value of export "${key}" must start with "./dist/" in package.json, got "${distPath}"`
841
- );
842
- }
843
- if (!distPath.endsWith(".js")) {
844
- throw new Error(
845
- `The default value of export "${key}" must end with ".js" in package.json, got "${distPath}"`
846
- );
847
- }
848
- const targetName = distPath.slice(7).slice(0, -3);
849
- return {
850
- entryPoint: `./src/${targetName}.ts`,
851
- targetName,
852
- distPath,
853
- isBin,
854
- key
855
- };
856
- }),
857
- mapKeys((_, value) => value.targetName)
858
- );
859
850
  const esbuildPlugins = [];
860
- const binSourceFilePaths = Object.values(entry).filter((value) => value.isBin).map((value) => value.entryPoint.slice(2));
851
+ const binSourceFilePaths = Object.values(entryPoints).filter((value) => value.isBin).map((value) => value.entryPoint.slice(2));
861
852
  if (this.library) {
862
853
  esbuildPlugins.push(schemaTransformerPlugin);
863
854
  }
@@ -865,7 +856,7 @@ var BuildCommand = class extends Command {
865
856
  esbuildPlugins.push(createBinTransformerPlugin(binSourceFilePaths));
866
857
  }
867
858
  await build({
868
- entry: mapValues(entry, (value) => value.entryPoint),
859
+ entry: mapValues(entryPoints, (value) => value.entryPoint),
869
860
  outDir: "dist",
870
861
  watch: this.watch,
871
862
  sourcemap: true,
@@ -888,14 +879,14 @@ var BuildCommand = class extends Command {
888
879
  logger
889
880
  );
890
881
  const distPathToExportKey = /* @__PURE__ */ new Map();
891
- for (const value of Object.values(entry)) {
882
+ for (const value of Object.values(entryPoints)) {
892
883
  distPathToExportKey.set(value.distPath, value.key);
893
884
  }
894
885
  await sourceHashCalculator.writeHighstateManifest("./dist", distPathToExportKey);
895
886
  }
896
887
  if (this.library) {
897
- const { loadLibrary } = await import('./library-loader-6TJTW2HX.js');
898
- const fullModulePaths = Object.values(entry).map((value) => resolve(value.distPath));
888
+ const { loadLibrary } = await import('./library-loader-PZWYMBAE.js');
889
+ const fullModulePaths = Object.values(entryPoints).map((value) => resolve(value.distPath));
899
890
  logger.info("evaluating library components from modules: %s", fullModulePaths.join(", "));
900
891
  const library = await loadLibrary(logger, fullModulePaths);
901
892
  const libraryPath = resolve("./dist", "highstate.library.msgpack");
@@ -904,31 +895,73 @@ var BuildCommand = class extends Command {
904
895
  logger.info("build completed successfully");
905
896
  }
906
897
  };
907
- var BackendIdentityCommand = class extends Command {
908
- static paths = [["backend", "identity"]];
898
+ var DesignerCommand = class extends Command {
899
+ static paths = [["designer"]];
909
900
  static usage = Command.Usage({
910
- category: "Backend",
911
- description: "Ensures the backend identity is set up and returns the recipient."
901
+ category: "Designer",
902
+ description: "Starts the Highstate designer in the current project."
912
903
  });
913
904
  async execute() {
914
- const backendLogger = logger.child({}, { msgPrefix: "[backend] " });
915
- const { getOrCreateBackendIdentity } = await import('@highstate/backend');
916
- const backendIdentity = await getOrCreateBackendIdentity(backendLogger);
917
- const recipient = await identityToRecipient(backendIdentity);
918
- logger.info(`stored backend identity is: ${recipient}`);
919
- logger.info(`run "highstate backend unlock-method add ${recipient}" on other authorized device`);
905
+ const packageJson = await readPackageJSON();
906
+ if (!packageJson.devDependencies?.["@highstate/cli"]) {
907
+ throw new UsageError(
908
+ "This project is not a Highstate project.\n@highstate/cli must be installed as a devDependency."
909
+ );
910
+ }
911
+ if (!packageJson.devDependencies?.["@highstate/designer"]) {
912
+ logger.info("Installing @highstate/designer...");
913
+ await addDevDependency(["@highstate/designer", "classic-level"]);
914
+ }
915
+ logger.info("starting highstate designer...");
916
+ await getBackendServices();
917
+ const oldConsoleLog = console.log;
918
+ const port = await getPort();
919
+ process.env.NITRO_PORT = port.toString();
920
+ process.env.NITRO_HOST = "0.0.0.0";
921
+ await new Promise((resolve4) => {
922
+ console.log = (message) => {
923
+ if (message.startsWith("Listening on")) {
924
+ resolve4();
925
+ }
926
+ };
927
+ const path = "@highstate/designer/.output/server/index.mjs";
928
+ void import(path);
929
+ });
930
+ console.log = oldConsoleLog;
931
+ consola.log(
932
+ [
933
+ "\n ",
934
+ colorize("bold", colorize("cyanBright", "Highstate Designer")),
935
+ "\n ",
936
+ colorize("greenBright", "\u279C Local: "),
937
+ colorize("underline", colorize("cyanBright", `http://localhost:${port}`)),
938
+ "\n"
939
+ ].join("")
940
+ );
941
+ process.on("SIGINT", () => {
942
+ process.stdout.write("\r");
943
+ consola.info("shutting down highstate designer...");
944
+ setTimeout(() => process.exit(0), 1e3);
945
+ });
920
946
  }
921
947
  };
922
- var UpdateReferencesCommand = class extends Command {
923
- static paths = [["package", "update-references"]];
948
+ var CreateCommand = class extends Command {
949
+ static paths = [["package", "create"]];
924
950
  static usage = Command.Usage({
925
951
  category: "Package",
926
- description: "Updates the root tsconfig.json with references to all packages in the workspace."
952
+ description: "Creates a new package in the workspace."
953
+ });
954
+ name = Option.String({ required: true });
955
+ type = Option.String("--type,-t", {
956
+ description: "Package type (source, library, worker)"
927
957
  });
928
958
  async execute() {
929
959
  const workspaceRoot = await findWorkspaceRoot();
960
+ const packageType = highstateConfigSchema.shape.type.parse(this.type);
961
+ await createPackage(workspaceRoot, this.name, packageType);
930
962
  const packages = await scanWorkspacePackages(workspaceRoot);
931
- await updateTsconfigReferences(workspaceRoot, packages, true);
963
+ await updateTsconfigReferences(workspaceRoot, packages);
964
+ console.log(`Created package: @highstate/${this.name} (${packageType})`);
932
965
  }
933
966
  };
934
967
  var ListCommand = class extends Command {
@@ -959,25 +992,6 @@ var ListCommand = class extends Command {
959
992
  }
960
993
  }
961
994
  };
962
- var CreateCommand = class extends Command {
963
- static paths = [["package", "create"]];
964
- static usage = Command.Usage({
965
- category: "Package",
966
- description: "Creates a new package in the workspace."
967
- });
968
- name = Option.String({ required: true });
969
- type = Option.String("--type,-t", {
970
- description: "Package type (source, library, worker)"
971
- });
972
- async execute() {
973
- const workspaceRoot = await findWorkspaceRoot();
974
- const packageType = highstateConfigSchema.shape.type.parse(this.type);
975
- await createPackage(workspaceRoot, this.name, packageType);
976
- const packages = await scanWorkspacePackages(workspaceRoot);
977
- await updateTsconfigReferences(workspaceRoot, packages);
978
- console.log(`Created package: @highstate/${this.name} (${packageType})`);
979
- }
980
- };
981
995
  var RemoveCommand = class extends Command {
982
996
  static paths = [["package", "remove"]];
983
997
  static usage = Command.Usage({
@@ -1001,6 +1015,18 @@ var RemoveCommand = class extends Command {
1001
1015
  console.log(`Removed package: ${targetPackage.name}`);
1002
1016
  }
1003
1017
  };
1018
+ var UpdateReferencesCommand = class extends Command {
1019
+ static paths = [["package", "update-references"]];
1020
+ static usage = Command.Usage({
1021
+ category: "Package",
1022
+ description: "Updates the root tsconfig.json with references to all packages in the workspace."
1023
+ });
1024
+ async execute() {
1025
+ const workspaceRoot = await findWorkspaceRoot();
1026
+ const packages = await scanWorkspacePackages(workspaceRoot);
1027
+ await updateTsconfigReferences(workspaceRoot, packages, true);
1028
+ }
1029
+ };
1004
1030
 
1005
1031
  // src/main.ts
1006
1032
  var cli = new Cli({