git-stint 0.1.1 → 0.2.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.
@@ -7,17 +7,22 @@
7
7
  */
8
8
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
9
9
  import { join, resolve } from "node:path";
10
+ /** Hook command names owned by git-stint. */
11
+ const STINT_COMMANDS = new Set([
12
+ "git-stint-hook-pre-tool",
13
+ "git-stint-hook-stop",
14
+ ]);
10
15
  const HOOKS = {
11
16
  hooks: {
12
17
  PreToolUse: [
13
18
  {
14
19
  matcher: "Write|Edit|NotebookEdit",
15
- command: "git-stint-hook-pre-tool",
20
+ hooks: [{ type: "command", command: "git-stint-hook-pre-tool" }],
16
21
  },
17
22
  ],
18
23
  Stop: [
19
24
  {
20
- command: "git-stint-hook-stop",
25
+ hooks: [{ type: "command", command: "git-stint-hook-stop" }],
21
26
  },
22
27
  ],
23
28
  },
@@ -39,13 +44,17 @@ export function install(scope) {
39
44
  settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
40
45
  }
41
46
  // Merge hooks (don't overwrite existing hooks)
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
48
  const hooks = (settings.hooks || {});
43
49
  for (const [event, hookList] of Object.entries(HOOKS.hooks)) {
44
50
  if (!hooks[event]) {
45
51
  hooks[event] = [];
46
52
  }
47
53
  for (const hook of hookList) {
48
- const exists = hooks[event].some((h) => h.command === hook.command);
54
+ const cmd = hook.hooks[0].command;
55
+ // Check both new format (hooks[].command) and old format (top-level command)
56
+ const exists = hooks[event].some((h) => h.hooks?.some((hh) => hh.command === cmd) ||
57
+ h.command === cmd);
49
58
  if (!exists) {
50
59
  hooks[event].push(hook);
51
60
  }
@@ -64,8 +73,16 @@ export function install(scope) {
64
73
  console.log(" PreToolUse (Write/Edit): track files in session worktrees");
65
74
  console.log(" Stop: commit pending changes as WIP checkpoint");
66
75
  }
67
- /** Known hook commands installed by git-stint. */
68
- const STINT_COMMANDS = new Set(Object.values(HOOKS.hooks).flat().map((h) => h.command));
76
+ /** Check if a hook entry (old or new format) contains a stint command. */
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ function isStintHook(h) {
79
+ // New format: { hooks: [{ type: "command", command: "..." }] }
80
+ if (Array.isArray(h.hooks)) {
81
+ return h.hooks.some((hh) => STINT_COMMANDS.has(hh.command));
82
+ }
83
+ // Old format: { command: "..." }
84
+ return STINT_COMMANDS.has(h.command);
85
+ }
69
86
  export function uninstall(scope) {
70
87
  const settingsPath = getSettingsPath(scope);
71
88
  if (!existsSync(settingsPath)) {
@@ -80,6 +97,7 @@ export function uninstall(scope) {
80
97
  console.error(`Failed to parse ${settingsPath}. Fix it manually.`);
81
98
  return;
82
99
  }
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
101
  const hooks = settings.hooks;
84
102
  if (!hooks) {
85
103
  console.log("No hooks configured. Nothing to uninstall.");
@@ -88,7 +106,7 @@ export function uninstall(scope) {
88
106
  let removed = 0;
89
107
  for (const event of Object.keys(hooks)) {
90
108
  const before = hooks[event].length;
91
- hooks[event] = hooks[event].filter((h) => !STINT_COMMANDS.has(h.command));
109
+ hooks[event] = hooks[event].filter((h) => !isStintHook(h));
92
110
  removed += before - hooks[event].length;
93
111
  // Remove empty arrays to keep settings clean
94
112
  if (hooks[event].length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-stint",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Session-scoped change tracking for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,6 +43,10 @@
43
43
  "branch-management",
44
44
  "developer-tools"
45
45
  ],
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "provenance": true
49
+ },
46
50
  "author": "Rahul Chandrasekaran",
47
51
  "license": "MIT",
48
52
  "devDependencies": {