@paradow/ledge 0.15.0 → 0.16.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.
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-R5462SQM.js";
8
8
 
9
9
  // src/cli/setup.ts
10
- import { readFile as readFile2, writeFile, mkdir, rename, realpath, rm, stat, lstat, readlink, symlink, unlink } from "fs/promises";
10
+ import { readFile as readFile2, writeFile, mkdir, rename, realpath, rm, stat, lstat, readlink } from "fs/promises";
11
11
  import { execFile } from "child_process";
12
12
  import { homedir, userInfo } from "os";
13
13
  import { join, dirname } from "path";
@@ -237,14 +237,23 @@ async function isDir(path) {
237
237
  return false;
238
238
  }
239
239
  }
240
- async function relinkBin(opts) {
240
+ var BIN_MARK = "#!/bin/sh\n# Written by `ledge setup`";
241
+ var shQuote = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
242
+ async function writeBin(opts) {
241
243
  const st = await lstat(opts.link).catch(() => null);
242
- if (!st?.isSymbolicLink()) return null;
243
- const current = await readlink(opts.link);
244
- if (current === opts.target || !current.endsWith("/dist/cli/index.js")) return null;
245
- await unlink(opts.link);
246
- await symlink(opts.target, opts.link);
247
- return `${opts.link} now points to ${opts.target} (was ${current})`;
244
+ const was = st?.isSymbolicLink() ? await readlink(opts.link) : null;
245
+ if (was !== null && !was.endsWith("/dist/cli/index.js")) return null;
246
+ const current = st && was === null && st.isFile() ? await readFile2(opts.link, "utf8").catch(() => "") : "";
247
+ if (st && was === null && !current.startsWith(BIN_MARK)) return null;
248
+ const script = `${BIN_MARK}: the hooks run \`ledge\` wherever node is not on the PATH.
249
+ exec ${shQuote(opts.node)} ${shQuote(opts.target)} "$@"
250
+ `;
251
+ if (current === script) return null;
252
+ await mkdir(dirname(opts.link), { recursive: true });
253
+ const tmp = `${opts.link}.tmp`;
254
+ await writeFile(tmp, script, { mode: 493 });
255
+ await rename(tmp, opts.link);
256
+ return `${opts.link} runs ${opts.target} with ${opts.node}${was !== null ? ` (was a link to ${was})` : ""}`;
248
257
  }
249
258
  async function runSetup(opts = {}) {
250
259
  const out = [];
@@ -262,13 +271,15 @@ async function runSetup(opts = {}) {
262
271
  if (!await isDir(cursorDir)) out.push(`Cursor Agent not found (${cursorDir} missing), Cursor Agent hooks skipped`);
263
272
  else if (await mergeJsonFile(join(cursorDir, "hooks.json"), mergeCursorHooks, "hooks.json")) out.push(`Cursor Agent hooks added in ${join(cursorDir, "hooks.json")}`);
264
273
  else out.push("Cursor Agent hooks already present");
265
- if ((opts.service ?? true) && !process.argv[1]?.endsWith(".ts")) {
266
- const line = await relinkBin({ link: join(homedir(), ".local", "bin", "ledge"), target: await realpath(process.argv[1]) });
267
- if (line) out.push(line);
268
- }
269
274
  if (opts.service ?? true) {
270
- if (process.argv[1]?.endsWith(".ts")) out.push("systemd service skipped: run setup from the built CLI (pnpm --filter @paradow/ledge build, then ledge setup)");
271
- else out.push(...await installService());
275
+ const cli = opts.cli ?? process.argv[1] ?? "";
276
+ if (cli.endsWith(".ts")) out.push("systemd service skipped: run setup from the built CLI (pnpm --filter @paradow/ledge build, then ledge setup)");
277
+ else {
278
+ const script = await realpath(cli);
279
+ const line = await writeBin({ link: opts.link ?? join(homedir(), ".local", "bin", "ledge"), node: process.execPath, target: script });
280
+ if (line) out.push(line);
281
+ out.push(...await installService({ script, unitDir: opts.unitDir, run: opts.run }));
282
+ }
272
283
  }
273
284
  return out;
274
285
  }
@@ -286,7 +297,8 @@ export {
286
297
  stopDetachedDaemon,
287
298
  installService,
288
299
  isDir,
289
- relinkBin,
300
+ BIN_MARK,
301
+ writeBin,
290
302
  runSetup,
291
303
  inDaemonService,
292
304
  tmuxServerAtRisk
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-PXO4FFJR.js";
3
+ } from "./chunk-DEXDXDO4.js";
4
4
  import {
5
5
  isArchived
6
- } from "./chunk-2LQITRTR.js";
6
+ } from "./chunk-Q5WWH7FG.js";
7
7
 
8
8
  // src/cli/who.ts
9
9
  import { basename } from "path";