skilldrop-cli 0.13.6 → 0.13.7

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.
Files changed (2) hide show
  1. package/bin/skilldrop.js +17 -5
  2. package/package.json +1 -1
package/bin/skilldrop.js CHANGED
@@ -252,7 +252,7 @@ function skillDir(cat, s) {
252
252
  // vanish in between and the read throws. Handle the absence, do not predict it.
253
253
  function readIfPresent(p, absent = "") {
254
254
  try { return fs.readFileSync(p, "utf8"); }
255
- catch (e) { if (e.code === "ENOENT") return absent; throw e; }
255
+ catch (e) { if (e.code === "ENOENT" || e.code === "ENOTDIR") return absent; throw e; }
256
256
  }
257
257
  function reEscape(s) { return String(s).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }
258
258
  function skillExists(cat, s) { const d = skillDir(cat, s); return !!d && fs.existsSync(d); }
@@ -651,9 +651,21 @@ function gitRoot(startDir) {
651
651
  }
652
652
  }
653
653
 
654
- // Append an idempotent, marker-fenced reminder to .git/hooks/pre-commit. IDE-agnostic.
654
+ /* Where git actually reads the pre-commit hook. In a worktree or a submodule .git is a file
655
+ ("gitdir: ..."), not a folder, and core.hooksPath can move hooks anywhere — so ask git, and
656
+ only fall back to .git/hooks when git isn't on the PATH. */
657
+ function preCommitPath(root) {
658
+ try {
659
+ const out = execFileSync("git", ["rev-parse", "--git-path", "hooks/pre-commit"],
660
+ { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
661
+ if (out) return path.resolve(root, out);
662
+ } catch (e) { /* no git binary, or not a repo after all */ }
663
+ return path.join(root, ".git", "hooks", "pre-commit");
664
+ }
665
+
666
+ // Append an idempotent, marker-fenced reminder to the repo's pre-commit hook. IDE-agnostic.
655
667
  function writeGitPreCommitHook(root, skill, hook) {
656
- const p = path.join(root, ".git", "hooks", "pre-commit");
668
+ const p = preCommitPath(root);
657
669
  const marker = `skilldrop-hook:${skill}:pre-commit-review`;
658
670
  let body = readIfPresent(p); // read-and-handle, not check-then-read
659
671
  if (!body.startsWith("#!")) body = "#!/bin/sh\n" + body;
@@ -695,7 +707,7 @@ function emitHooks(cat, skill, dest, ide) {
695
707
  for (const h of hooks) {
696
708
  if (h.event === "pre-commit-review") {
697
709
  const root = gitRoot(process.cwd());
698
- if (root) lines.push(` ${skill}: pre-commit reminder -> ${path.join(root, ".git/hooks/pre-commit")}`);
710
+ if (root) lines.push(` ${skill}: pre-commit reminder -> ${preCommitPath(root)}`);
699
711
  else lines.push(` ${skill}: pre-commit-review skipped — no git repo at ${process.cwd()}`);
700
712
  if (root) writeGitPreCommitHook(root, skill, h);
701
713
  } else if (h.event === "session-start") {
@@ -717,7 +729,7 @@ function emitHooks(cat, skill, dest, ide) {
717
729
  function removeHooksFor(skill, dest, ide) {
718
730
  const root = gitRoot(process.cwd());
719
731
  if (root) {
720
- const p = path.join(root, ".git", "hooks", "pre-commit");
732
+ const p = preCommitPath(root);
721
733
  const body = readIfPresent(p, null);
722
734
  if (body !== null) {
723
735
  const q = reEscape(skill);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilldrop-cli",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "description": "Portable AI-agent skills for the deliverables knowledge workers ship \u2014 diagrams, ADRs, PRDs, runbooks, decks, reviews \u2014 installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
5
5
  "author": {
6
6
  "name": "Sanjay Ananthanarayan",