@bitsocial/bitsocial-cli 0.19.73 → 0.19.75

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
@@ -421,7 +421,7 @@ EXAMPLES
421
421
  $ bitsocial challenge install ./my-local-challenge
422
422
  ```
423
423
 
424
- _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/challenge/install.ts)_
424
+ _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/challenge/install.ts)_
425
425
 
426
426
  ## `bitsocial challenge list`
427
427
 
@@ -447,7 +447,7 @@ EXAMPLES
447
447
  $ bitsocial challenge list -q
448
448
  ```
449
449
 
450
- _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/challenge/list.ts)_
450
+ _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/challenge/list.ts)_
451
451
 
452
452
  ## `bitsocial challenge ls`
453
453
 
@@ -501,7 +501,7 @@ EXAMPLES
501
501
  $ bitsocial challenge remove @scope/my-challenge
502
502
  ```
503
503
 
504
- _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/challenge/remove.ts)_
504
+ _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/challenge/remove.ts)_
505
505
 
506
506
  ## `bitsocial challenge rm NAME`
507
507
 
@@ -615,7 +615,7 @@ EXAMPLES
615
615
  $ bitsocial community create --jsonFile ./create-options.json
616
616
  ```
617
617
 
618
- _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/create.ts)_
618
+ _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/create.ts)_
619
619
 
620
620
  ## `bitsocial community delete ADDRESSES`
621
621
 
@@ -640,7 +640,7 @@ EXAMPLES
640
640
  $ bitsocial community delete 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
641
641
  ```
642
642
 
643
- _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/delete.ts)_
643
+ _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/delete.ts)_
644
644
 
645
645
  ## `bitsocial community edit ADDRESS`
646
646
 
@@ -710,7 +710,7 @@ EXAMPLES
710
710
  $ bitsocial community edit bitsocial.bso --jsonFile ./edit-options.json
711
711
  ```
712
712
 
713
- _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/edit.ts)_
713
+ _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/edit.ts)_
714
714
 
715
715
  ## `bitsocial community export [ADDRESS]`
716
716
 
@@ -751,7 +751,7 @@ EXAMPLES
751
751
  $ bitsocial community export --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
752
752
  ```
753
753
 
754
- _See code: [src/cli/commands/community/export.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/export.ts)_
754
+ _See code: [src/cli/commands/community/export.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/export.ts)_
755
755
 
756
756
  ## `bitsocial community get [ADDRESS]`
757
757
 
@@ -782,7 +782,7 @@ EXAMPLES
782
782
  $ bitsocial community get --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
783
783
  ```
784
784
 
785
- _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/get.ts)_
785
+ _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/get.ts)_
786
786
 
787
787
  ## `bitsocial community list`
788
788
 
@@ -805,7 +805,7 @@ EXAMPLES
805
805
  $ bitsocial community list
806
806
  ```
807
807
 
808
- _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/list.ts)_
808
+ _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/list.ts)_
809
809
 
810
810
  ## `bitsocial community start ADDRESSES`
811
811
 
@@ -839,7 +839,7 @@ EXAMPLES
839
839
  $ bitsocial community start $(bitsocial community list -q) --concurrency 1
840
840
  ```
841
841
 
842
- _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/start.ts)_
842
+ _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/start.ts)_
843
843
 
844
844
  ## `bitsocial community stop ADDRESSES`
845
845
 
@@ -864,7 +864,7 @@ EXAMPLES
864
864
  $ bitsocial community stop Qmb99crTbSUfKXamXwZBe829Vf6w5w5TktPkb6WstC9RFW
865
865
  ```
866
866
 
867
- _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/community/stop.ts)_
867
+ _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/community/stop.ts)_
868
868
 
869
869
  ## `bitsocial daemon`
870
870
 
@@ -911,7 +911,7 @@ EXAMPLES
911
911
  $ bitsocial daemon --no-allowPrivateKeyExport
912
912
  ```
913
913
 
914
- _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/daemon.ts)_
914
+ _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/daemon.ts)_
915
915
 
916
916
  ## `bitsocial help [COMMAND]`
917
917
 
@@ -977,7 +977,7 @@ EXAMPLES
977
977
  $ bitsocial logs --stdout -f
978
978
  ```
979
979
 
980
- _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/logs.ts)_
980
+ _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/logs.ts)_
981
981
 
982
982
  ## `bitsocial update check`
983
983
 
@@ -994,7 +994,7 @@ EXAMPLES
994
994
  $ bitsocial update check
995
995
  ```
996
996
 
997
- _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/update/check.ts)_
997
+ _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/update/check.ts)_
998
998
 
999
999
  ## `bitsocial update install [VERSION]`
1000
1000
 
@@ -1026,7 +1026,7 @@ EXAMPLES
1026
1026
  $ bitsocial update install --no-restart-daemons
1027
1027
  ```
1028
1028
 
1029
- _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/update/install.ts)_
1029
+ _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/update/install.ts)_
1030
1030
 
1031
1031
  ## `bitsocial update versions`
1032
1032
 
@@ -1048,7 +1048,7 @@ EXAMPLES
1048
1048
  $ bitsocial update versions --limit 5
1049
1049
  ```
1050
1050
 
1051
- _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.73/src/cli/commands/update/versions.ts)_
1051
+ _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.75/src/cli/commands/update/versions.ts)_
1052
1052
  <!-- commandsstop -->
1053
1053
 
1054
1054
  ## Contribution
@@ -210,6 +210,12 @@ export default class Daemon extends Command {
210
210
  this._setupLogger(PKCLogger);
211
211
  const { logFilePath, stdoutWrite } = await this._pipeDebugLogsToLogFile(flags.logPath, PKCLogger);
212
212
  const log = PKCLogger("bitsocial-cli:daemon");
213
+ // Captured once the async exit hook is registered (inside the try). The startup-failure
214
+ // catch and the force-quit signal guard use these to run kubo/daemon cleanup and drop the
215
+ // hook before the process exits via process.exit() — which would otherwise skip the async
216
+ // hook (exit-hook's "SYNCHRONOUS TERMINATION NOTICE") and orphan kubo. (issue #98)
217
+ let runDaemonShutdown;
218
+ let removeAsyncExitHook;
213
219
  try {
214
220
  // Log debug info after pipe is set up so it goes to the log file, not terminal
215
221
  const envDebug = process.env["_PKC_DEBUG"] || process.env["DEBUG"];
@@ -417,6 +423,13 @@ export default class Daemon extends Command {
417
423
  return;
418
424
  if (startedOwnRpc)
419
425
  return;
426
+ // Test hook (issue #98): force a startup failure *after* keepKuboUp() has already
427
+ // spawned kubo, reproducing the real TOCTOU port race (createOrConnectRpc throwing
428
+ // once kubo is up). Verifies the daemon tears kubo down — and doesn't print
429
+ // exit-hook's "SYNCHRONOUS TERMINATION NOTICE" — when oclif process.exit()s on a
430
+ // thrown startup error, instead of orphaning kubo.
431
+ if (process.env["PKC_CLI_TEST_FAIL_AFTER_KUBO_START"])
432
+ throw new Error("Simulated startup failure after kubo start (PKC_CLI_TEST_FAIL_AFTER_KUBO_START)");
420
433
  // Re-check the port: the early fail-fast at startup is a few ms before this runs,
421
434
  // so a TOCTOU race could let another process grab the port in between. If that
422
435
  // happens we must fail rather than silently leaving the daemon without an RPC.
@@ -530,7 +543,7 @@ export default class Daemon extends Command {
530
543
  killKuboProcessGroup(pid, "SIGKILL");
531
544
  liveKuboPids.clear();
532
545
  };
533
- asyncExitHook(async () => {
546
+ const shutdownDaemon = async () => {
534
547
  if (keepKuboUpInterval)
535
548
  clearInterval(keepKuboUpInterval);
536
549
  if (mainProcessExited)
@@ -552,8 +565,16 @@ export default class Daemon extends Command {
552
565
  log.error("Error shutting down daemon server", e);
553
566
  }
554
567
  await kuboKillPromise;
555
- }, { wait: DAEMON_SHUTDOWN_TIMEOUT_MS } // could take two minutes to shut down
568
+ };
569
+ // Run kubo/daemon cleanup on SIGINT/SIGTERM/beforeExit. Capture the unsubscribe handle
570
+ // and the shutdown fn so the startup-failure catch (and the force-quit guard below) can
571
+ // run cleanup themselves and drop this hook: oclif calls process.exit() as it unwinds a
572
+ // thrown startup error, and process.exit() runs only synchronous exit hooks — exit-hook
573
+ // would skip this async one (printing its "SYNCHRONOUS TERMINATION NOTICE") and orphan a
574
+ // kubo we already spawned. (issue #98)
575
+ removeAsyncExitHook = asyncExitHook(shutdownDaemon, { wait: DAEMON_SHUTDOWN_TIMEOUT_MS } // could take two minutes to shut down
556
576
  );
577
+ runDaemonShutdown = shutdownDaemon;
557
578
  // Emergency cleanup: if the process force-exits (e.g. double Ctrl+C),
558
579
  // synchronously SIGKILL every live kubo's process group. This is a no-op if
559
580
  // killKuboProcess() already ran (it clears kuboProcess and liveKuboPids).
@@ -578,6 +599,11 @@ export default class Daemon extends Command {
578
599
  terminationSignalCount++;
579
600
  if (terminationSignalCount >= 2) {
580
601
  log(`Received ${signal} again during shutdown, force-quitting`);
602
+ // Deliberate immediate exit: the first signal's async shutdown is still
603
+ // running but the user wants out now. Drop the async exit hook first so the
604
+ // imminent process.exit() doesn't trip exit-hook's "SYNCHRONOUS TERMINATION
605
+ // NOTICE"; kubo is still SIGKILLed by the emergency "exit" handler. (issue #98)
606
+ removeAsyncExitHook?.();
581
607
  process.exit(signal === "SIGINT" ? 130 : 143);
582
608
  }
583
609
  });
@@ -641,6 +667,20 @@ export default class Daemon extends Command {
641
667
  }
642
668
  stdoutWrite(`Full log: ${logFilePath}\n`);
643
669
  stdoutWrite(`Or run: bitsocial logs\n`);
670
+ // oclif's error handler calls process.exit() as it unwinds this throw, which runs only
671
+ // synchronous exit hooks — exit-hook would skip the async kubo/daemon cleanup (printing
672
+ // "SYNCHRONOUS TERMINATION NOTICE") and orphan a kubo we may have already spawned, and
673
+ // leave this daemon's state file behind. Run that cleanup now and drop the now-redundant
674
+ // hook so the process exits clean. No-ops if we failed before the hook was registered.
675
+ // Cap the wait with the same DAEMON_SHUTDOWN_TIMEOUT_MS the signal path gets (via the
676
+ // exit-hook `wait` option) so a hung daemonServer.destroy() can't swallow the original
677
+ // startup error forever; the unref'd timer never keeps the loop alive. (issue #98)
678
+ if (runDaemonShutdown)
679
+ await Promise.race([
680
+ runDaemonShutdown().catch(() => { }),
681
+ new Promise((resolve) => setTimeout(resolve, DAEMON_SHUTDOWN_TIMEOUT_MS).unref())
682
+ ]);
683
+ removeAsyncExitHook?.();
644
684
  throw err;
645
685
  }
646
686
  }
@@ -871,5 +871,5 @@
871
871
  ]
872
872
  }
873
873
  },
874
- "version": "0.19.73"
874
+ "version": "0.19.75"
875
875
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitsocial/bitsocial-cli",
3
- "version": "0.19.73",
3
+ "version": "0.19.75",
4
4
  "description": "Command line interface to Bitsocial API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "homepage": "https://github.com/bitsocialnet/bitsocial-cli",
@@ -119,7 +119,7 @@
119
119
  "@oclif/plugin-help": "6.2.36",
120
120
  "@oclif/plugin-not-found": "3.2.73",
121
121
  "@oclif/table": "0.5.1",
122
- "@pkcprotocol/pkc-js": "0.0.48",
122
+ "@pkcprotocol/pkc-js": "0.0.50",
123
123
  "dataobject-parser": "1.2.22",
124
124
  "decompress": "4.2.1",
125
125
  "env-paths": "2.2.1",