@zeph-to/hook-sdk 1.0.1 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AA0IA,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAG,OAAO,CAAC,MAAM,CAgH1F,CAAC"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAyNA,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAG,OAAO,CAAC,MAAM,CAmH1F,CAAC"}
package/dist/installer.js CHANGED
@@ -7,6 +7,7 @@ const path_1 = require("path");
7
7
  const readline_1 = require("readline");
8
8
  const zeph_hook_js_1 = require("./zeph-hook.js");
9
9
  const config_js_1 = require("./config.js");
10
+ const templates_js_1 = require("./templates.js");
10
11
  const HOME = process.env.HOME ?? '~';
11
12
  // ── Helpers ──────────────────────────────────────────────────────
12
13
  const ok = (msg) => console.log(` + ${msg}`);
@@ -29,12 +30,28 @@ const hasCommand = (cmd) => {
29
30
  return false;
30
31
  }
31
32
  };
33
+ const writeFile = (filePath, content) => {
34
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(filePath), { recursive: true });
35
+ (0, fs_1.writeFileSync)(filePath, content + '\n');
36
+ };
37
+ const mergeJsonFile = (filePath, patch) => {
38
+ let data = {};
39
+ try {
40
+ data = JSON.parse((0, fs_1.readFileSync)(filePath, 'utf-8'));
41
+ }
42
+ catch { /* new file */ }
43
+ const merged = { ...data, ...patch };
44
+ writeFile(filePath, JSON.stringify(merged, null, 2));
45
+ };
32
46
  // ── Agent Detection ──────────────────────────────────────────────
33
47
  const detectAgents = () => [
34
48
  { name: 'Claude Code', id: 'claude', detected: hasCommand('claude') },
35
49
  { name: 'Cursor', id: 'cursor', detected: (0, fs_1.existsSync)((0, path_1.join)(HOME, '.cursor')) },
36
50
  { name: 'Windsurf', id: 'windsurf', detected: (0, fs_1.existsSync)((0, path_1.join)(HOME, '.codeium')) },
37
51
  { name: 'Gemini CLI', id: 'gemini', detected: hasCommand('gemini') },
52
+ { name: 'Codex CLI', id: 'codex', detected: hasCommand('codex') },
53
+ { name: 'Copilot CLI', id: 'copilot', detected: (0, fs_1.existsSync)((0, path_1.join)(HOME, '.copilot')) },
54
+ { name: 'Cline', id: 'cline', detected: (0, fs_1.existsSync)((0, path_1.join)(HOME, '.cline')) },
38
55
  ];
39
56
  // ── Per-Agent Installers ─────────────────────────────────────────
40
57
  const injectMcpJson = (filePath) => {
@@ -67,20 +84,41 @@ const installClaude = () => {
67
84
  const installCursor = () => {
68
85
  try {
69
86
  injectMcpJson((0, path_1.join)(HOME, '.cursor', 'mcp.json'));
70
- ok('MCP server added to ~/.cursor/mcp.json');
87
+ ok('MCP server added');
71
88
  }
72
89
  catch {
73
90
  fail('MCP injection failed. Manual: add zeph to ~/.cursor/mcp.json');
74
91
  }
92
+ try {
93
+ writeFile((0, path_1.join)(HOME, '.cursor', 'hooks.json'), templates_js_1.CURSOR_HOOKS);
94
+ ok('Stop hook added');
95
+ }
96
+ catch {
97
+ fail('Hook install failed');
98
+ }
99
+ try {
100
+ writeFile((0, path_1.join)(HOME, '.cursor', 'rules', 'zeph.mdc'), templates_js_1.CURSOR_RULE);
101
+ ok('Rule file added');
102
+ }
103
+ catch {
104
+ fail('Rule install failed');
105
+ }
75
106
  };
76
107
  const installWindsurf = () => {
77
108
  try {
78
109
  injectMcpJson((0, path_1.join)(HOME, '.codeium', 'windsurf', 'mcp_config.json'));
79
- ok('MCP server added to ~/.codeium/windsurf/mcp_config.json');
110
+ ok('MCP server added');
80
111
  }
81
112
  catch {
82
113
  fail('MCP injection failed. Manual: add zeph to windsurf mcp_config.json');
83
114
  }
115
+ try {
116
+ writeFile((0, path_1.join)(HOME, '.codeium', 'windsurf', 'hooks.json'), templates_js_1.WINDSURF_HOOKS);
117
+ ok('Response hook added');
118
+ }
119
+ catch {
120
+ fail('Hook install failed');
121
+ }
84
122
  };
85
123
  const installGemini = () => {
86
124
  try {
@@ -90,12 +128,49 @@ const installGemini = () => {
90
128
  catch {
91
129
  fail('MCP add failed. Manual: gemini mcp add zeph -- npx -y @zeph-to/mcp-server');
92
130
  }
131
+ try {
132
+ mergeJsonFile((0, path_1.join)(HOME, '.gemini', 'settings.json'), templates_js_1.GEMINI_HOOKS);
133
+ ok('AfterAgent hook added');
134
+ }
135
+ catch {
136
+ fail('Hook install failed');
137
+ }
138
+ };
139
+ const installCodex = () => {
140
+ try {
141
+ writeFile((0, path_1.join)(HOME, '.codex', 'hooks.json'), templates_js_1.CODEX_HOOKS);
142
+ ok('Stop hook added');
143
+ }
144
+ catch {
145
+ fail('Hook install failed. Manual: add zeph to ~/.codex/hooks.json');
146
+ }
147
+ };
148
+ const installCopilot = () => {
149
+ try {
150
+ writeFile((0, path_1.join)(HOME, '.copilot', 'hooks', 'zeph.json'), templates_js_1.COPILOT_HOOKS);
151
+ ok('Session end hook added');
152
+ }
153
+ catch {
154
+ fail('Hook install failed. Manual: add zeph to ~/.copilot/hooks/');
155
+ }
156
+ };
157
+ const installCline = () => {
158
+ try {
159
+ writeFile((0, path_1.join)(HOME, '.cline', 'rules', 'zeph.md'), templates_js_1.CLINE_RULE);
160
+ ok('Rule file added');
161
+ }
162
+ catch {
163
+ fail('Rule install failed. Manual: add zeph to ~/.cline/rules/');
164
+ }
93
165
  };
94
166
  const AGENT_INSTALLERS = {
95
167
  claude: installClaude,
96
168
  cursor: installCursor,
97
169
  windsurf: installWindsurf,
98
170
  gemini: installGemini,
171
+ codex: installCodex,
172
+ copilot: installCopilot,
173
+ cline: installCline,
99
174
  };
100
175
  // ── Test Connection ──────────────────────────────────────────────
101
176
  const testConnection = async (apiKey, baseUrl) => {
@@ -175,9 +250,12 @@ const handleInstall = async (args) => {
175
250
  for (const agent of detected) {
176
251
  const labels = {
177
252
  claude: 'Install Claude Code plugin',
178
- cursor: 'Add MCP server to ~/.cursor/mcp.json',
179
- windsurf: 'Add MCP server to windsurf mcp_config.json',
180
- gemini: 'Add MCP server to Gemini CLI',
253
+ cursor: 'Setup Cursor (MCP + hooks + rules)',
254
+ windsurf: 'Setup Windsurf (MCP + hooks)',
255
+ gemini: 'Setup Gemini CLI (MCP + hooks)',
256
+ codex: 'Setup Codex CLI (hooks)',
257
+ copilot: 'Setup Copilot CLI (hooks)',
258
+ cline: 'Setup Cline (rules)',
181
259
  };
182
260
  console.log(` ${step}. ${labels[agent.id] ?? `Install for ${agent.name}`}`);
183
261
  step++;
@@ -0,0 +1,23 @@
1
+ export declare const CURSOR_HOOKS: string;
2
+ export declare const CURSOR_RULE = "---\ndescription: \"Zeph notification rules\"\nalwaysApply: true\n---\n\nWhen you complete a coding task, call the zeph_notify MCP tool with a brief summary.\nUse zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.\nDo not notify for trivial operations (file reads, simple searches).\n";
3
+ export declare const WINDSURF_HOOKS: string;
4
+ export declare const WINDSURF_RULE = "When you complete a coding task, call the zeph_notify MCP tool with a brief summary.\nUse zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.\nDo not notify for trivial operations (file reads, simple searches).\n";
5
+ export declare const GEMINI_HOOKS: {
6
+ hooks: {
7
+ AfterAgent: {
8
+ matcher: string;
9
+ hooks: {
10
+ name: string;
11
+ type: string;
12
+ command: string;
13
+ }[];
14
+ }[];
15
+ };
16
+ hooksConfig: {
17
+ enabled: boolean;
18
+ };
19
+ };
20
+ export declare const CODEX_HOOKS: string;
21
+ export declare const COPILOT_HOOKS: string;
22
+ export declare const CLINE_RULE = "When you complete a coding task, call the zeph_notify MCP tool with a brief summary.\nUse zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.\nDo not notify for trivial operations (file reads, simple searches).\n";
23
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,QAOd,CAAC;AAEZ,eAAO,MAAM,WAAW,+TAQvB,CAAC;AAIF,eAAO,MAAM,cAAc,QAOhB,CAAC;AAEZ,eAAO,MAAM,aAAa,sPAGzB,CAAC;AAIF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAYxB,CAAC;AAIF,eAAO,MAAM,WAAW,QAQb,CAAC;AAIZ,eAAO,MAAM,aAAa,QASf,CAAC;AAIZ,eAAO,MAAM,UAAU,sPAGtB,CAAC"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ // ── Hook & Rule templates for each agent ─────────────────────────
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.CLINE_RULE = exports.COPILOT_HOOKS = exports.CODEX_HOOKS = exports.GEMINI_HOOKS = exports.WINDSURF_RULE = exports.WINDSURF_HOOKS = exports.CURSOR_RULE = exports.CURSOR_HOOKS = void 0;
5
+ const NOTIFY_CMD = 'npx @zeph-to/hook-sdk notify --title "Task done" 2>/dev/null || true';
6
+ // ── Cursor ───────────────────────────────────────────────────────
7
+ exports.CURSOR_HOOKS = JSON.stringify({
8
+ version: 1,
9
+ hooks: {
10
+ stop: [{
11
+ command: NOTIFY_CMD,
12
+ }],
13
+ },
14
+ }, null, 2);
15
+ exports.CURSOR_RULE = `---
16
+ description: "Zeph notification rules"
17
+ alwaysApply: true
18
+ ---
19
+
20
+ When you complete a coding task, call the zeph_notify MCP tool with a brief summary.
21
+ Use zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.
22
+ Do not notify for trivial operations (file reads, simple searches).
23
+ `;
24
+ // ── Windsurf ─────────────────────────────────────────────────────
25
+ exports.WINDSURF_HOOKS = JSON.stringify({
26
+ hooks: {
27
+ post_cascade_response: [{
28
+ command: NOTIFY_CMD,
29
+ show_output: false,
30
+ }],
31
+ },
32
+ }, null, 2);
33
+ exports.WINDSURF_RULE = `When you complete a coding task, call the zeph_notify MCP tool with a brief summary.
34
+ Use zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.
35
+ Do not notify for trivial operations (file reads, simple searches).
36
+ `;
37
+ // ── Gemini ───────────────────────────────────────────────────────
38
+ exports.GEMINI_HOOKS = {
39
+ hooks: {
40
+ AfterAgent: [{
41
+ matcher: '*',
42
+ hooks: [{
43
+ name: 'zeph-notify',
44
+ type: 'command',
45
+ command: NOTIFY_CMD,
46
+ }],
47
+ }],
48
+ },
49
+ hooksConfig: { enabled: true },
50
+ };
51
+ // ── Codex ────────────────────────────────────────────────────────
52
+ exports.CODEX_HOOKS = JSON.stringify({
53
+ version: 1,
54
+ hooks: {
55
+ Stop: [{
56
+ type: 'command',
57
+ bash: NOTIFY_CMD,
58
+ }],
59
+ },
60
+ }, null, 2);
61
+ // ── Copilot ──────────────────────────────────────────────────────
62
+ exports.COPILOT_HOOKS = JSON.stringify({
63
+ version: 1,
64
+ hooks: {
65
+ sessionEnd: [{
66
+ type: 'command',
67
+ bash: NOTIFY_CMD,
68
+ timeoutSec: 10,
69
+ }],
70
+ },
71
+ }, null, 2);
72
+ // ── Cline ────────────────────────────────────────────────────────
73
+ exports.CLINE_RULE = `When you complete a coding task, call the zeph_notify MCP tool with a brief summary.
74
+ Use zeph_prompt for user decisions (2-4 options). Use zeph_input for free-form text.
75
+ Do not notify for trivial operations (file reads, simple searches).
76
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeph-to/hook-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Zeph push notification SDK + CLI — zero dependencies",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",