@holochain/hc-spin 0.600.0 → 0.700.0-dev.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/CHANGELOG.md CHANGED
@@ -9,6 +9,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
9
9
  ### Changed
10
10
  ### Removed
11
11
 
12
+ ## 2026-01-13: v0.700.0-dev.0
13
+ ### Changed
14
+ - Updated to holochain 0.7.0-dev.7
15
+
16
+ ## 2025-11-20: v0.600.0
17
+ ### Added
18
+ - A new argument `--force-admin-ports` takes a comma-separated list of port numbers, to force generated conductors to use specific admin ports. [#50](https://github.com/holochain/hc-spin/pull/50)
19
+
12
20
  ## 2025-11-06: v0.600.0-rc.0
13
21
 
14
22
  ### Added
package/README.md CHANGED
@@ -4,12 +4,12 @@ CLI to run Holochain apps in development mode.
4
4
 
5
5
  ## Installation
6
6
 
7
- To install the latest version compatible with **holochain 0.4.x**:
7
+ To install the latest version compatible with **holochain 0.6.x**:
8
8
 
9
- ⚠️ Requires `@holochain/client 0.18.0` or newer ⚠️
9
+ ⚠️ Requires `@holochain/client 0.20.0` or newer ⚠️
10
10
 
11
11
  ```sh
12
- npm install --save-dev @holochain/hc-spin@">=0.400.0 <0.500.0"
12
+ npm install --save-dev @holochain/hc-spin@">=0.600.0 <0.700.0"
13
13
  ```
14
14
 
15
15
  To install the latest version compatible with **holochain 0.5.x**:
@@ -20,12 +20,12 @@ To install the latest version compatible with **holochain 0.5.x**:
20
20
  npm install --save-dev @holochain/hc-spin@">=0.500.0 <0.600.0"
21
21
  ```
22
22
 
23
- To install the latest version compatible with **holochain 0.6.x**:
23
+ To install the latest version compatible with **holochain 0.4.x**:
24
24
 
25
- ⚠️ Requires `@holochain/client 0.20.0` or newer ⚠️
25
+ ⚠️ Requires `@holochain/client 0.18.0` or newer ⚠️
26
26
 
27
27
  ```sh
28
- npm install --save-dev @holochain/hc-spin@">=0.600.0 <0.700.0"
28
+ npm install --save-dev @holochain/hc-spin@">=0.400.0 <0.500.0"
29
29
  ```
30
30
 
31
31
  ## Usage (holochain 0.6)
@@ -12432,6 +12432,18 @@ function validateCliArgs(cliArgs, cliOpts, appDataRootDir) {
12432
12432
  const appId = cliOpts.appId ? cliOpts.appId : path.parse(path.basename(cliArgs[0])).name;
12433
12433
  const holochainPath = cliOpts.holochainPath;
12434
12434
  const numAgents = cliOpts.numAgents ? cliOpts.numAgents : 2;
12435
+ let forceAdminPorts;
12436
+ if (cliOpts.forceAdminPorts !== void 0) {
12437
+ forceAdminPorts = cliOpts.forceAdminPorts.split(",").map((portStr) => {
12438
+ const portInt = parseInt(portStr);
12439
+ if (Number.isNaN(portInt)) {
12440
+ throw new Error(
12441
+ `The --force-admin-ports must be a comma-separated list of valid port numbers, but got: ${cliOpts.forceAdminPorts}`
12442
+ );
12443
+ }
12444
+ return portInt;
12445
+ });
12446
+ }
12435
12447
  return {
12436
12448
  appId,
12437
12449
  holochainPath,
@@ -12442,7 +12454,8 @@ function validateCliArgs(cliArgs, cliOpts, appDataRootDir) {
12442
12454
  singalingUrl: cliOpts.signalingUrl,
12443
12455
  bootstrapUrl: cliOpts.bootstrapUrl,
12444
12456
  happOrWebhappPath: isHapp ? { type: "happ", path: happOrWebhappPath } : { type: "webhapp", path: happOrWebhappPath },
12445
- openDevtools: cliOpts.openDevtools ? true : false
12457
+ openDevtools: cliOpts.openDevtools ? true : false,
12458
+ forceAdminPorts
12446
12459
  };
12447
12460
  }
12448
12461
  async function createHappWindow(uiSource, appId, agentNum, appPort, appAuthToken, appDataRootDir) {
@@ -12563,7 +12576,7 @@ function setLinkOpenHandlers(browserWindow) {
12563
12576
  }
12564
12577
  const rustUtils = require("@holochain/hc-spin-rust-utils");
12565
12578
  const cli = new commander.Command();
12566
- cli.name("hc-spin").description("CLI to run Holochain apps during development.").version(`${"0.600.0"} (built for holochain ${"0.6.0"})`).argument(
12579
+ cli.name("hc-spin").description("CLI to run Holochain apps during development.").version(`${"0.700.0-dev.0"} (built for holochain ${"0.7.0-dev.7"})`).argument(
12567
12580
  "<path>",
12568
12581
  "Path to .webhapp or .happ file to launch. If a .happ file is passed, either a UI path must be specified via --ui-path or a port pointing to a localhost server via --ui-port"
12569
12582
  ).option(
@@ -12587,6 +12600,9 @@ cli.name("hc-spin").description("CLI to run Holochain apps during development.")
12587
12600
  ).option(
12588
12601
  "--signaling-url <url>",
12589
12602
  "Url of the signaling server to use. By default, hc spin spins up a local development signaling server for you but this argument allows you to specify a custom one."
12603
+ ).option(
12604
+ "--force-admin-ports <ports>",
12605
+ "A comma-separated list of port numbers for the holochain conductors to bind to their admin interfaces. By default, hc spin picks any available ports."
12590
12606
  ).option("--open-devtools", "Automatically open the devtools on startup.");
12591
12607
  cli.parse();
12592
12608
  const rl = require("readline").createInterface({
@@ -12686,9 +12702,12 @@ async function startLocalServices() {
12686
12702
  });
12687
12703
  });
12688
12704
  }
12689
- async function spawnSandboxes(nAgents, happPath, bootStrapUrl, signalUrl, appId, networkSeed, targetArcFactor) {
12690
- const generateArgs = [
12691
- "sandbox",
12705
+ async function spawnSandboxes(nAgents, happPath, bootStrapUrl, signalUrl, appId, networkSeed, targetArcFactor, forceAdminPorts) {
12706
+ const generateArgs = ["sandbox"];
12707
+ if (forceAdminPorts !== void 0 && forceAdminPorts.length > 0) {
12708
+ generateArgs.push("--force-admin-ports", forceAdminPorts.join(","));
12709
+ }
12710
+ generateArgs.push(
12692
12711
  "--piped",
12693
12712
  "generate",
12694
12713
  "--num-sandboxes",
@@ -12696,7 +12715,7 @@ async function spawnSandboxes(nAgents, happPath, bootStrapUrl, signalUrl, appId,
12696
12715
  "--app-id",
12697
12716
  appId,
12698
12717
  "--run"
12699
- ];
12718
+ );
12700
12719
  let appPorts = "";
12701
12720
  for (let i = 1; i <= nAgents; i++) {
12702
12721
  const appPort = await getPorts();
@@ -12748,7 +12767,7 @@ electron.app.whenReady().then(async () => {
12748
12767
  if (CLI_OPTS.happOrWebhappPath.type === "webhapp") {
12749
12768
  happTargetDir = path.join(DATA_ROOT_DIR, "apps", CLI_OPTS.appId);
12750
12769
  const uiTargetDir = path.join(happTargetDir, "ui");
12751
- await rustUtils.saveHappOrWebhapp(
12770
+ await rustUtils.unpackAndSaveWebhapp(
12752
12771
  CLI_OPTS.happOrWebhappPath.path,
12753
12772
  CLI_OPTS.appId,
12754
12773
  uiTargetDir,
@@ -12763,7 +12782,8 @@ electron.app.whenReady().then(async () => {
12763
12782
  CLI_OPTS.singalingUrl ? CLI_OPTS.singalingUrl : signalingUrl,
12764
12783
  CLI_OPTS.appId,
12765
12784
  CLI_OPTS.networkSeed,
12766
- CLI_OPTS.targetArcFactor
12785
+ CLI_OPTS.targetArcFactor,
12786
+ CLI_OPTS.forceAdminPorts
12767
12787
  );
12768
12788
  const lairUrls = [];
12769
12789
  sandboxPaths.forEach((sandbox) => {
package/docs/DEVSETUP.md CHANGED
@@ -25,3 +25,15 @@ yarn build
25
25
  ```bash
26
26
  yarn start <path to .webhapp file>
27
27
  ```
28
+
29
+ ## Upgrade hc-spin to a new holochain version
30
+
31
+ 0. Update the flake.nix file if necessary and run `nix flake update`.
32
+ 1. Upgrade the upstream `@holochain/hc-spin-rust-utils` package [in this repo](https://github.com/holochain/hc-spin-rust-utils), following the instructions in its README. This may involve manual testing of a locally built `@holochain/hc-spin-rust-utils` here in the hc-spin repo. In that case, make sure to have entered nix shell with `nix develop` before testing, such that the correct holochain binary is being used by hc-spin.
33
+ 2. Once the new `@holochain/hc-spin-rust-utils` package has been upgraded and released, update it accordingly in the `package.json` file.
34
+ 3. Update `@holochain/client` in the `package.json` file to the appropriate version.
35
+ 4. Check whether any code changes are necessary after updating the packages. Once the code has been adapted, test it with `yarn start <path to .webhapp file>`.
36
+ 5. If testing succeeds, update the `version` field in `package.json`.
37
+ 6. Make any changes as necessary to the README. The README is what is shown on npmjs.org as the package description so it should be up to date.
38
+ 7. Build the hc-spin binary with `yarn build`.
39
+ 8. And finally publish it with `npm publish`.
package/flake.lock CHANGED
@@ -2,11 +2,11 @@
2
2
  "nodes": {
3
3
  "crane": {
4
4
  "locked": {
5
- "lastModified": 1762189950,
6
- "narHash": "sha256-aotggLUXjlDGqKWibGPQcMZJGgdr79S21ISrv1Wz6RI=",
5
+ "lastModified": 1763511871,
6
+ "narHash": "sha256-KKZWi+ij7oT0Ag8yC6MQkzfHGcytyjMJDD+47ZV1YNU=",
7
7
  "owner": "ipetkov",
8
8
  "repo": "crane",
9
- "rev": "50700219af884287ad7c85507e2f163b23a027a9",
9
+ "rev": "099f9014bc8d0cd6e445470ea1df0fd691d5a548",
10
10
  "type": "github"
11
11
  },
12
12
  "original": {
@@ -20,11 +20,11 @@
20
20
  "nixpkgs-lib": "nixpkgs-lib"
21
21
  },
22
22
  "locked": {
23
- "lastModified": 1762040540,
24
- "narHash": "sha256-z5PlZ47j50VNF3R+IMS9LmzI5fYRGY/Z5O5tol1c9I4=",
23
+ "lastModified": 1762980239,
24
+ "narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=",
25
25
  "owner": "hercules-ci",
26
26
  "repo": "flake-parts",
27
- "rev": "0010412d62a25d959151790968765a70c436598b",
27
+ "rev": "52a2caecc898d0b46b2b905f058ccc5081f842da",
28
28
  "type": "github"
29
29
  },
30
30
  "original": {
@@ -33,36 +33,19 @@
33
33
  "type": "github"
34
34
  }
35
35
  },
36
- "hc-launch": {
37
- "flake": false,
38
- "locked": {
39
- "lastModified": 1752056054,
40
- "narHash": "sha256-iLHhGQXrSfgAibzLSx+mdOQnnTzq4mrRXto7+a+MDLM=",
41
- "owner": "holochain",
42
- "repo": "hc-launch",
43
- "rev": "612aa244ceb4d2136e5adbf181ff0cc123daff65",
44
- "type": "github"
45
- },
46
- "original": {
47
- "owner": "holochain",
48
- "ref": "holochain-weekly",
49
- "repo": "hc-launch",
50
- "type": "github"
51
- }
52
- },
53
36
  "hc-scaffold": {
54
37
  "flake": false,
55
38
  "locked": {
56
- "lastModified": 1760566803,
57
- "narHash": "sha256-fWflEEb2JQyVHfGglbx6dCR6X+4ECGM9pbxQYrKSZtQ=",
39
+ "lastModified": 1764163563,
40
+ "narHash": "sha256-KigJ3h25yNJfeQunPm5QYFPtLSk6nU3IEEvZY8w01Vo=",
58
41
  "owner": "holochain",
59
42
  "repo": "scaffolding",
60
- "rev": "751a16e98ddb35db5763cbf4b882a849b642e7e7",
43
+ "rev": "87e997a7361d4aa7c1bb96261483ebba50223bd0",
61
44
  "type": "github"
62
45
  },
63
46
  "original": {
64
47
  "owner": "holochain",
65
- "ref": "0.600.0-dev.0",
48
+ "ref": "v0.600.1",
66
49
  "repo": "scaffolding",
67
50
  "type": "github"
68
51
  }
@@ -70,16 +53,16 @@
70
53
  "holochain": {
71
54
  "flake": false,
72
55
  "locked": {
73
- "lastModified": 1762372467,
74
- "narHash": "sha256-8LoKyzjkAoHOlJ0+8hUrwc0LTX7/2TdVODoLwMZMNVA=",
56
+ "lastModified": 1768178786,
57
+ "narHash": "sha256-JsYqXKZMkt4v0hd7dA3GCs8ELuLEoiectSY4Zw9pWJw=",
75
58
  "owner": "holochain",
76
59
  "repo": "holochain",
77
- "rev": "90f56b5bf15b572cd9fdbd63d5a40a288143ff5f",
60
+ "rev": "6594a0ed6a038113bc55e0c1545310736189d88b",
78
61
  "type": "github"
79
62
  },
80
63
  "original": {
81
64
  "owner": "holochain",
82
- "ref": "holochain-0.6.0-rc.0",
65
+ "ref": "holochain-0.7.0-dev.7",
83
66
  "repo": "holochain",
84
67
  "type": "github"
85
68
  }
@@ -88,7 +71,6 @@
88
71
  "inputs": {
89
72
  "crane": "crane",
90
73
  "flake-parts": "flake-parts",
91
- "hc-launch": "hc-launch",
92
74
  "hc-scaffold": "hc-scaffold",
93
75
  "holochain": "holochain",
94
76
  "kitsune2": "kitsune2",
@@ -98,11 +80,11 @@
98
80
  "rust-overlay": "rust-overlay"
99
81
  },
100
82
  "locked": {
101
- "lastModified": 1762431364,
102
- "narHash": "sha256-769gbrsWU5SejCYcvoTPkVakU8nj5qYUw6cDlMRIgDs=",
83
+ "lastModified": 1768299200,
84
+ "narHash": "sha256-wg7yUc/n6iYf5/qgV2tosZimJu0iTLVZOouko95TuiM=",
103
85
  "owner": "holochain",
104
86
  "repo": "holonix",
105
- "rev": "2682fec89ecb743c13453a65ee775147076f1919",
87
+ "rev": "70c034a9eedfd3d48450432f938b86dc11202361",
106
88
  "type": "github"
107
89
  },
108
90
  "original": {
@@ -115,16 +97,16 @@
115
97
  "kitsune2": {
116
98
  "flake": false,
117
99
  "locked": {
118
- "lastModified": 1762303720,
119
- "narHash": "sha256-tC2k+1kPxpVYRYJLWYXQPvFlUwgfF4cKoFKbkak0vxU=",
100
+ "lastModified": 1763403287,
101
+ "narHash": "sha256-dqQJMoDbcD0ekttrv5+8ph5Yf25EdXwKktsxNjV57Iw=",
120
102
  "owner": "holochain",
121
103
  "repo": "kitsune2",
122
- "rev": "112099b30381ea0d23b8b3af21f5b5bb81ced6c5",
104
+ "rev": "22de6e42100aa960d05f5f30427a236ad922bd80",
123
105
  "type": "github"
124
106
  },
125
107
  "original": {
126
108
  "owner": "holochain",
127
- "ref": "v0.3.0",
109
+ "ref": "v0.3.2",
128
110
  "repo": "kitsune2",
129
111
  "type": "github"
130
112
  }
@@ -148,11 +130,11 @@
148
130
  },
149
131
  "nixpkgs": {
150
132
  "locked": {
151
- "lastModified": 1762233356,
152
- "narHash": "sha256-cGS3lLTYusbEP/IJIWGgnkzIl+FA5xDvtiHyjalGr4k=",
133
+ "lastModified": 1763622513,
134
+ "narHash": "sha256-1jQnuyu82FpiSxowrF/iFK6Toh9BYprfDqfs4BB+19M=",
153
135
  "owner": "nixos",
154
136
  "repo": "nixpkgs",
155
- "rev": "ca534a76c4afb2bdc07b681dbc11b453bab21af8",
137
+ "rev": "c58bc7f5459328e4afac201c5c4feb7c818d604b",
156
138
  "type": "github"
157
139
  },
158
140
  "original": {
@@ -215,11 +197,11 @@
215
197
  ]
216
198
  },
217
199
  "locked": {
218
- "lastModified": 1762396738,
219
- "narHash": "sha256-BarSecuxtzp1boERdABLkkoxQTi6s/V33lJwUbWLrLY=",
200
+ "lastModified": 1763692705,
201
+ "narHash": "sha256-tCKCyMYU0Vy+ph/xswlNsYXXjnFVweWBV+ew/5FS9tA=",
220
202
  "owner": "oxalica",
221
203
  "repo": "rust-overlay",
222
- "rev": "c63598992afd54d215d54f2b764adc0484c2b159",
204
+ "rev": "6fbf5d328dce1828d887b8ee7d44a785196a34e7",
223
205
  "type": "github"
224
206
  },
225
207
  "original": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@holochain/hc-spin",
3
- "version": "0.600.0",
4
- "holochainVersion": "0.6.0",
3
+ "version": "0.700.0-dev.0",
4
+ "holochainVersion": "0.7.0-dev.7",
5
5
  "description": "CLI to run Holochain apps during development.",
6
6
  "author": "matthme",
7
7
  "homepage": "https://developer.holochain.org",
@@ -36,7 +36,7 @@
36
36
  "@electron-toolkit/preload": "^3.0.0",
37
37
  "@electron-toolkit/utils": "^3.0.0",
38
38
  "@holochain/client": "^0.20.0",
39
- "@holochain/hc-spin-rust-utils": "0.600.0",
39
+ "@holochain/hc-spin-rust-utils": "0.700.0-dev.0",
40
40
  "@msgpack/msgpack": "^2.8.0",
41
41
  "bufferutil": "4.0.8",
42
42
  "commander": "11.1.0",
package/src/main/index.ts CHANGED
@@ -66,6 +66,10 @@ cli
66
66
  '--signaling-url <url>',
67
67
  'Url of the signaling server to use. By default, hc spin spins up a local development signaling server for you but this argument allows you to specify a custom one.',
68
68
  )
69
+ .option(
70
+ '--force-admin-ports <ports>',
71
+ 'A comma-separated list of port numbers for the holochain conductors to bind to their admin interfaces. By default, hc spin picks any available ports.',
72
+ )
69
73
  .option('--open-devtools', 'Automatically open the devtools on startup.');
70
74
 
71
75
  cli.parse();
@@ -211,11 +215,17 @@ async function spawnSandboxes(
211
215
  appId: string,
212
216
  networkSeed?: string,
213
217
  targetArcFactor?: number,
218
+ forceAdminPorts?: number[],
214
219
  ): Promise<
215
220
  [childProcess.ChildProcessWithoutNullStreams, Array<string>, Record<number, PortsInfo>]
216
221
  > {
217
- const generateArgs = [
218
- 'sandbox',
222
+ const generateArgs = ['sandbox'];
223
+
224
+ if (forceAdminPorts !== undefined && forceAdminPorts.length > 0) {
225
+ generateArgs.push('--force-admin-ports', forceAdminPorts.join(','));
226
+ }
227
+
228
+ generateArgs.push(
219
229
  '--piped',
220
230
  'generate',
221
231
  '--num-sandboxes',
@@ -223,7 +233,8 @@ async function spawnSandboxes(
223
233
  '--app-id',
224
234
  appId,
225
235
  '--run',
226
- ];
236
+ );
237
+
227
238
  let appPorts = '';
228
239
  for (let i = 1; i <= nAgents; i++) {
229
240
  const appPort = await getPort();
@@ -294,7 +305,7 @@ app.whenReady().then(async () => {
294
305
  if (CLI_OPTS.happOrWebhappPath.type === 'webhapp') {
295
306
  happTargetDir = path.join(DATA_ROOT_DIR, 'apps', CLI_OPTS.appId);
296
307
  const uiTargetDir = path.join(happTargetDir, 'ui');
297
- await rustUtils.saveHappOrWebhapp(
308
+ await rustUtils.unpackAndSaveWebhapp(
298
309
  CLI_OPTS.happOrWebhappPath.path,
299
310
  CLI_OPTS.appId,
300
311
  uiTargetDir,
@@ -312,6 +323,7 @@ app.whenReady().then(async () => {
312
323
  CLI_OPTS.appId,
313
324
  CLI_OPTS.networkSeed,
314
325
  CLI_OPTS.targetArcFactor,
326
+ CLI_OPTS.forceAdminPorts,
315
327
  );
316
328
 
317
329
  const lairUrls: string[] = [];
@@ -14,6 +14,7 @@ export type CliOpts = {
14
14
  signalingUrl?: string;
15
15
  bootstrapUrl?: string;
16
16
  openDevtools?: boolean;
17
+ forceAdminPorts?: string;
17
18
  };
18
19
 
19
20
  export type CliOptsValidated = {
@@ -27,6 +28,7 @@ export type CliOptsValidated = {
27
28
  bootstrapUrl: string | undefined;
28
29
  happOrWebhappPath: HappOrWebhappPath;
29
30
  openDevtools: boolean;
31
+ forceAdminPorts: number[] | undefined;
30
32
  };
31
33
 
32
34
  export type HappOrWebhappPath = {
@@ -87,6 +89,20 @@ export function validateCliArgs(
87
89
  const holochainPath = cliOpts.holochainPath;
88
90
  const numAgents = cliOpts.numAgents ? cliOpts.numAgents : 2;
89
91
 
92
+ let forceAdminPorts: number[] | undefined;
93
+ if (cliOpts.forceAdminPorts !== undefined) {
94
+ forceAdminPorts = cliOpts.forceAdminPorts.split(',').map((portStr) => {
95
+ const portInt = parseInt(portStr);
96
+
97
+ if (Number.isNaN(portInt)) {
98
+ throw new Error(
99
+ `The --force-admin-ports must be a comma-separated list of valid port numbers, but got: ${cliOpts.forceAdminPorts}`,
100
+ );
101
+ }
102
+ return portInt;
103
+ });
104
+ }
105
+
90
106
  return {
91
107
  appId,
92
108
  holochainPath,
@@ -104,5 +120,6 @@ export function validateCliArgs(
104
120
  ? { type: 'happ', path: happOrWebhappPath }
105
121
  : { type: 'webhapp', path: happOrWebhappPath },
106
122
  openDevtools: cliOpts.openDevtools ? true : false,
123
+ forceAdminPorts,
107
124
  };
108
125
  }