sealcode 1.3.0 → 1.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sealcode",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Lock your source code in your own git repo. Stop AI agents, scrapers, and curious eyes from reading what's yours.",
5
5
  "keywords": [
6
6
  "encryption",
package/src/cli-watch.js CHANGED
@@ -314,6 +314,7 @@ function startExfilWatchers({
314
314
  encoding: 'utf8',
315
315
  timeout: 1500,
316
316
  stdio: ['ignore', 'pipe', 'ignore'],
317
+ windowsHide: true,
317
318
  })
318
319
  .trim();
319
320
  } catch (_) { /* repo may not have git */ }
@@ -417,6 +418,7 @@ function startExfilWatchers({
417
418
  const cur = cp
418
419
  .execFileSync('git', ['-C', projectAbs, 'remote', '-v'], {
419
420
  encoding: 'utf8', timeout: 1500, stdio: ['ignore', 'pipe', 'ignore'],
421
+ windowsHide: true,
420
422
  })
421
423
  .trim();
422
424
  if (initialRemotes && cur !== initialRemotes) {
@@ -932,9 +934,33 @@ async function finalLock(projectRoot, config, code, reason, json, daemon) {
932
934
  * Helper: spawn a detached `sealcode watch <code> --daemon` child. Used
933
935
  * by runUnlock when the unlock came from a grant-derived session.
934
936
  * Returns the child pid (already detached). Best-effort.
937
+ *
938
+ * Windows specifics (sealcode@1.3.1):
939
+ * - `windowsHide: true` keeps the spawned process from popping a
940
+ * console window. Without this, every daemon spawn flashes a black
941
+ * cmd window which users (rightly) find alarming.
942
+ * - We also guard against re-spawn loops: if a daemon is already
943
+ * alive for this project we just return its pid instead of
944
+ * spawning a new one. Without this guard, repeated `redeem` calls
945
+ * (or any startup hook that re-runs redeem) accumulate orphan
946
+ * daemons that each show up as a pop-and-vanish window when they
947
+ * periodically run their child-process sweeps.
935
948
  */
936
949
  function spawnDaemonWatcher({ projectRoot, code }) {
937
950
  try {
951
+ // If a healthy daemon is already running for this project, don't
952
+ // start another one. This is the single most important defense
953
+ // against the "windows pop in and out" loop on Windows.
954
+ const existing = readWatcherStatus(projectRoot);
955
+ if (existing.state === 'alive') {
956
+ return { pid: existing.pid, reused: true };
957
+ }
958
+ // Stale / dead state file should be cleared before respawn, otherwise
959
+ // the new daemon may collide with leftover bookkeeping.
960
+ if (existing.state === 'stale' || existing.state === 'dead') {
961
+ try { fs.unlinkSync(watchStateFile(projectRoot)); } catch (_) { /* ignore */ }
962
+ }
963
+
938
964
  ensureDir(WATCH_LOG_DIR);
939
965
  const bin = process.execPath;
940
966
  const entry = require.resolve('../bin/sealcode.js');
@@ -945,6 +971,9 @@ function spawnDaemonWatcher({ projectRoot, code }) {
945
971
  cwd: projectRoot,
946
972
  detached: true,
947
973
  stdio: 'ignore',
974
+ // Critical on Windows — without this, the spawned daemon
975
+ // opens a visible cmd window. macOS / Linux ignore the flag.
976
+ windowsHide: true,
948
977
  env: { ...process.env, SEALCODE_AUTO_DAEMON: '1' },
949
978
  },
950
979
  );
package/src/device.js CHANGED
@@ -72,6 +72,9 @@ function readMachineId() {
72
72
  encoding: 'utf8',
73
73
  timeout: 1500,
74
74
  stdio: ['ignore', 'pipe', 'ignore'],
75
+ // Stop reg.exe from flashing a console window — happens on every
76
+ // command run because device.js is loaded by `clientInfo()`.
77
+ windowsHide: true,
75
78
  });
76
79
  const m = /MachineGuid\s+REG_SZ\s+([0-9a-f-]+)/i.exec(out);
77
80
  return m ? m[1] : null;