localdeck 1.2.1 → 1.2.2

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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>LocalDeck</title>
7
7
  <link rel="icon" type="image/png" href="/localdeck-icon.png" />
8
- <script type="module" crossorigin src="/assets/index-BzX_uJtU.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-BDrE-iT3.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-DbQzubLF.css">
10
10
  </head>
11
11
  <body>
@@ -2991,6 +2991,11 @@ var PORTS_FILE = path.join(HOME_DIR, "ports.json");
2991
2991
  var PROJECTS_FILE = path.join(HOME_DIR, "projects.json");
2992
2992
  var DAEMON_LOG = path.join(HOME_DIR, "daemon.log");
2993
2993
  var DEFAULT_API_PORT = Number(process.env.LOCALDECK_PORT ?? 7777);
2994
+ function assertUserRuntime(uid = process.getuid?.(), env = process.env) {
2995
+ if (uid === 0 && env.SUDO_UID && env.SUDO_UID !== "0") {
2996
+ throw new Error("Do not launch or update the LocalDeck runtime with sudo. Run localdeck daemon start as your normal user. If installation requires administrator access, run sudo npm install -g localdeck@latest separately, then start LocalDeck without sudo.");
2997
+ }
2998
+ }
2994
2999
  function ensureDirs() {
2995
3000
  fs.mkdirSync(LOGS_DIR, { recursive: true });
2996
3001
  }
@@ -8143,11 +8148,12 @@ async function waitForProcessGroupExit(groupId, timeoutMs) {
8143
8148
  return true;
8144
8149
  }
8145
8150
  // ../daemon/package.json
8146
- var version = "1.2.1";
8151
+ var version = "1.2.2";
8147
8152
 
8148
8153
  // ../daemon/src/index.ts
8149
8154
  var VERSION = version;
8150
8155
  async function startDaemon(opts = {}) {
8156
+ assertUserRuntime();
8151
8157
  ensureDirs();
8152
8158
  const dependencies = {
8153
8159
  createStore: () => new Store,
@@ -8294,8 +8300,19 @@ function createOperationTracker() {
8294
8300
  };
8295
8301
  return { track, waitForIdle };
8296
8302
  }
8297
- async function findDaemon() {
8298
- const state = readJson(STATE_FILE, null);
8303
+ async function findDaemon(stateFile = STATE_FILE) {
8304
+ let state;
8305
+ try {
8306
+ state = JSON.parse(fs10.readFileSync(stateFile, "utf8"));
8307
+ } catch (error) {
8308
+ const code = error.code;
8309
+ if (code === "EACCES" || code === "EPERM") {
8310
+ throw new Error(`Cannot read LocalDeck daemon state at ${stateFile}: permission denied. The daemon may still be running under another user (often after sudo). If it was started with sudo, run sudo localdeck daemon stop, then localdeck daemon start without sudo. Do not make the state file world-readable; it contains a private control token.`);
8311
+ }
8312
+ if (code === "ENOENT" || error instanceof SyntaxError)
8313
+ return null;
8314
+ throw new Error(`Cannot read LocalDeck daemon state at ${stateFile}${code ? ` (${code})` : ""}. Check the file and directory permissions.`);
8315
+ }
8299
8316
  if (!state)
8300
8317
  return null;
8301
8318
  try {
@@ -8337,6 +8354,7 @@ function daemonCommand() {
8337
8354
  return [process.execPath, [entry, "daemon", "run"]];
8338
8355
  }
8339
8356
  async function ensureDaemon() {
8357
+ assertUserRuntime();
8340
8358
  const running = await findDaemon();
8341
8359
  if (running)
8342
8360
  return running;
@@ -8410,4 +8428,4 @@ class Api {
8410
8428
  shutdown = () => this.call("POST", "/api/shutdown");
8411
8429
  }
8412
8430
 
8413
- export { __toESM, __commonJS, __export, __require, wrapper_default, startForwarder, HOME_DIR, STATE_FILE, DEFAULT_API_PORT, findProjectFile, loadProject, loadProjectFile, shellCommand, isPortFree, getFreePort, serviceKey, processTree, listeningPorts, chooseUpstream, connectHost, streamLines, killProcessTree, stripAnsi, redactDiagnostic, environmentValues, listProjectSecrets, resolveProjectSecrets, startupGuidance, inferPortEnvironment, startupLayers, waitForReadiness, secretOutput, VERSION, startDaemon, findDaemon, dashboardDir, ensureDaemon, Api };
8431
+ export { __toESM, __commonJS, __export, __require, wrapper_default, startForwarder, HOME_DIR, STATE_FILE, DEFAULT_API_PORT, assertUserRuntime, findProjectFile, loadProject, loadProjectFile, shellCommand, isPortFree, getFreePort, serviceKey, processTree, listeningPorts, chooseUpstream, connectHost, streamLines, killProcessTree, stripAnsi, redactDiagnostic, environmentValues, listProjectSecrets, resolveProjectSecrets, startupGuidance, inferPortEnvironment, startupLayers, waitForReadiness, secretOutput, VERSION, startDaemon, findDaemon, dashboardDir, ensureDaemon, Api };
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  stripAnsi,
31
31
  waitForReadiness,
32
32
  wrapper_default
33
- } from "./index-19n321tr.js";
33
+ } from "./index-q0ecp96f.js";
34
34
 
35
35
  // src/index.ts
36
36
  import { spawn as spawn2 } from "node:child_process";
@@ -907,13 +907,13 @@ async function main(argv, overrides = {}) {
907
907
  case "--update":
908
908
  if (rest.length)
909
909
  throw new Error("Usage: localdeck --update");
910
- return (await import("./update-nx00r38m.js")).updateLocalDeck();
910
+ return (await import("./update-5pz3der1.js")).updateLocalDeck();
911
911
  case "up":
912
912
  return cmdUp(rest, dependencies);
913
913
  case "init":
914
914
  return cmdInit(rest, dependencies);
915
915
  case "mcp":
916
- return (await import("./mcp-vkez9mq7.js")).runMcp(rest);
916
+ return (await import("./mcp-pwywe3ff.js")).runMcp(rest);
917
917
  case "doctor":
918
918
  return cmdDoctor(rest);
919
919
  case "forward":
@@ -9,7 +9,7 @@ import {
9
9
  listProjectSecrets,
10
10
  redactDiagnostic,
11
11
  resolveProjectSecrets
12
- } from "./index-19n321tr.js";
12
+ } from "./index-q0ecp96f.js";
13
13
 
14
14
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
15
15
  var require_code = __commonJS((exports) => {
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  Api,
3
3
  STATE_FILE,
4
+ assertUserRuntime,
4
5
  findDaemon
5
- } from "./index-19n321tr.js";
6
+ } from "./index-q0ecp96f.js";
6
7
 
7
8
  // src/update.ts
8
9
  import { spawn } from "node:child_process";
@@ -63,6 +64,7 @@ async function applyUpdate(steps) {
63
64
  return version;
64
65
  }
65
66
  async function updateLocalDeck() {
67
+ assertUserRuntime();
66
68
  const root = fs.realpathSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."));
67
69
  const npm = npmCommand();
68
70
  const globalRoot = await execute([...npm, "root", "--global"], true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localdeck",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "description": "Stable ports, shareable HTTPS links and request logs for your local dev servers",
6
6
  "bin": {