agentwake 1.0.0 → 1.0.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.
Files changed (58) hide show
  1. package/.cursor/hooks.json +2 -2
  2. package/README.md +210 -80
  3. package/dist/adapters/claude-hook-adapter.d.ts.map +1 -1
  4. package/dist/adapters/claude-hook-adapter.js +67 -0
  5. package/dist/adapters/claude-hook-adapter.js.map +1 -1
  6. package/dist/adapters/cursor-hook-adapter.d.ts.map +1 -1
  7. package/dist/adapters/cursor-hook-adapter.js +133 -47
  8. package/dist/adapters/cursor-hook-adapter.js.map +1 -1
  9. package/dist/adapters/cursor-terminal-hook.d.ts +12 -0
  10. package/dist/adapters/cursor-terminal-hook.d.ts.map +1 -1
  11. package/dist/adapters/cursor-terminal-hook.js +158 -4
  12. package/dist/adapters/cursor-terminal-hook.js.map +1 -1
  13. package/dist/adapters/qoder-log-adapter.d.ts +9 -0
  14. package/dist/adapters/qoder-log-adapter.d.ts.map +1 -1
  15. package/dist/adapters/qoder-log-adapter.js +188 -19
  16. package/dist/adapters/qoder-log-adapter.js.map +1 -1
  17. package/dist/bootstrap.d.ts.map +1 -1
  18. package/dist/bootstrap.js +25 -5
  19. package/dist/bootstrap.js.map +1 -1
  20. package/dist/cli.js +82 -19
  21. package/dist/cli.js.map +1 -1
  22. package/dist/config.d.ts +12 -0
  23. package/dist/config.d.ts.map +1 -1
  24. package/dist/config.js +45 -3
  25. package/dist/config.js.map +1 -1
  26. package/dist/installers/claude-code-installer.d.ts +15 -0
  27. package/dist/installers/claude-code-installer.d.ts.map +1 -0
  28. package/dist/installers/claude-code-installer.js +109 -0
  29. package/dist/installers/claude-code-installer.js.map +1 -0
  30. package/dist/notifiers/dingtalk-notifier.d.ts +15 -0
  31. package/dist/notifiers/dingtalk-notifier.d.ts.map +1 -0
  32. package/dist/notifiers/dingtalk-notifier.js +52 -0
  33. package/dist/notifiers/dingtalk-notifier.js.map +1 -0
  34. package/dist/notifiers/feishu-notifier.d.ts +14 -0
  35. package/dist/notifiers/feishu-notifier.d.ts.map +1 -0
  36. package/dist/notifiers/feishu-notifier.js +60 -0
  37. package/dist/notifiers/feishu-notifier.js.map +1 -0
  38. package/dist/notifiers/wecom-notifier.d.ts +13 -0
  39. package/dist/notifiers/wecom-notifier.d.ts.map +1 -0
  40. package/dist/notifiers/wecom-notifier.js +39 -0
  41. package/dist/notifiers/wecom-notifier.js.map +1 -0
  42. package/dist/paths.d.ts +9 -0
  43. package/dist/paths.d.ts.map +1 -0
  44. package/dist/paths.js +27 -0
  45. package/dist/paths.js.map +1 -0
  46. package/dist/run-gateway.d.ts +0 -1
  47. package/dist/run-gateway.d.ts.map +1 -1
  48. package/dist/run-gateway.js +11 -1
  49. package/dist/run-gateway.js.map +1 -1
  50. package/dist/setup.d.ts +2 -0
  51. package/dist/setup.d.ts.map +1 -0
  52. package/dist/setup.js +274 -0
  53. package/dist/setup.js.map +1 -0
  54. package/dist/utils/logger.d.ts.map +1 -1
  55. package/dist/utils/logger.js +20 -2
  56. package/dist/utils/logger.js.map +1 -1
  57. package/package.json +4 -2
  58. package/scripts/cursor-hook-forwarder.mjs +50 -4
package/dist/setup.js ADDED
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.runSetup = runSetup;
40
+ const prompts_1 = require("@inquirer/prompts");
41
+ const node_fs_1 = require("node:fs");
42
+ const node_os_1 = __importDefault(require("node:os"));
43
+ const node_path_1 = __importDefault(require("node:path"));
44
+ const claude_code_installer_1 = require("./installers/claude-code-installer");
45
+ const paths_1 = require("./paths");
46
+ const CLAUDE_CODE_EVENTS = [
47
+ { name: "Notification — 需要用户注意时", value: "Notification", defaultEnabled: true },
48
+ { name: "Stop — 任务完成停止时", value: "Stop", defaultEnabled: true },
49
+ { name: "StopFailure — 任务失败停止时", value: "StopFailure", defaultEnabled: true },
50
+ { name: "SessionEnd — 会话结束时", value: "SessionEnd", defaultEnabled: true },
51
+ { name: "SessionStart — 会话开始时", value: "SessionStart", defaultEnabled: false },
52
+ { name: "PreToolUse — 工具调用前", value: "PreToolUse", defaultEnabled: false },
53
+ { name: "PostToolUse — 工具调用后", value: "PostToolUse", defaultEnabled: false },
54
+ ];
55
+ function getLocalIp() {
56
+ const interfaces = node_os_1.default.networkInterfaces();
57
+ for (const addrs of Object.values(interfaces)) {
58
+ if (!addrs)
59
+ continue;
60
+ for (const addr of addrs) {
61
+ if (addr.family === "IPv4" && !addr.internal) {
62
+ return addr.address;
63
+ }
64
+ }
65
+ }
66
+ return null;
67
+ }
68
+ function readEnvFile(envPath) {
69
+ if (!(0, node_fs_1.existsSync)(envPath))
70
+ return {};
71
+ const raw = (0, node_fs_1.readFileSync)(envPath, "utf8");
72
+ const result = {};
73
+ for (const line of raw.split("\n")) {
74
+ const trimmed = line.trim();
75
+ if (!trimmed || trimmed.startsWith("#"))
76
+ continue;
77
+ const eqIdx = trimmed.indexOf("=");
78
+ if (eqIdx < 0)
79
+ continue;
80
+ const key = trimmed.slice(0, eqIdx).trim();
81
+ let val = trimmed.slice(eqIdx + 1).trim();
82
+ // Strip surrounding quotes
83
+ if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
84
+ val = val.slice(1, -1);
85
+ }
86
+ result[key] = val;
87
+ }
88
+ return result;
89
+ }
90
+ function writeEnvFile(envPath, vars) {
91
+ // Read existing content to preserve comments and ordering
92
+ let lines = [];
93
+ if ((0, node_fs_1.existsSync)(envPath)) {
94
+ lines = (0, node_fs_1.readFileSync)(envPath, "utf8").split("\n");
95
+ }
96
+ const written = new Set();
97
+ // Update existing lines
98
+ for (let i = 0; i < lines.length; i++) {
99
+ const trimmed = lines[i].trim();
100
+ if (!trimmed || trimmed.startsWith("#"))
101
+ continue;
102
+ const eqIdx = trimmed.indexOf("=");
103
+ if (eqIdx < 0)
104
+ continue;
105
+ const key = trimmed.slice(0, eqIdx).trim();
106
+ if (key in vars) {
107
+ lines[i] = `${key}=${vars[key]}`;
108
+ written.add(key);
109
+ }
110
+ }
111
+ // Append new vars
112
+ for (const [key, value] of Object.entries(vars)) {
113
+ if (!written.has(key)) {
114
+ lines.push(`${key}=${value}`);
115
+ }
116
+ }
117
+ (0, node_fs_1.writeFileSync)(envPath, lines.join("\n").trimEnd() + "\n", "utf8");
118
+ }
119
+ async function runSetup() {
120
+ console.log("\n🔧 AgentWake 配置向导\n");
121
+ (0, paths_1.ensureHome)();
122
+ const envPath = (0, paths_1.homePath)(".env");
123
+ // Step 1: Select AI tool
124
+ const aiTool = await (0, prompts_1.select)({
125
+ message: "选择要配置的 AI 工具",
126
+ choices: [
127
+ { name: "Claude Code", value: "claude-code" },
128
+ { name: "Cursor", value: "cursor" },
129
+ { name: "全部", value: "all" },
130
+ ],
131
+ });
132
+ // Step 2: Select Claude Code events (if applicable)
133
+ let selectedEvents = [];
134
+ if (aiTool === "claude-code" || aiTool === "all") {
135
+ selectedEvents = await (0, prompts_1.checkbox)({
136
+ message: "选择要监听的 Claude Code 事件",
137
+ choices: CLAUDE_CODE_EVENTS.map((e) => ({
138
+ name: e.name,
139
+ value: e.value,
140
+ checked: e.defaultEnabled,
141
+ })),
142
+ });
143
+ }
144
+ // Step 2.5: Customize notification titles per event
145
+ const eventTitleVars = {};
146
+ if (selectedEvents.length > 0) {
147
+ const wantCustom = await (0, prompts_1.confirm)({
148
+ message: "是否自定义每个事件的通知标题?(否则使用默认标题)",
149
+ default: false,
150
+ });
151
+ if (wantCustom) {
152
+ const defaultTitles = {
153
+ Stop: "Claude Code: 任务完成",
154
+ StopFailure: "Claude Code: 任务异常终止",
155
+ Notification: "Claude Code: 需要你的注意",
156
+ SessionEnd: "Claude Code: 会话已结束",
157
+ SessionStart: "Claude Code: 会话已开始",
158
+ PreToolUse: "Claude Code: 工具调用前",
159
+ PostToolUse: "Claude Code: 工具调用后",
160
+ };
161
+ for (const evt of selectedEvents) {
162
+ const defaultTitle = defaultTitles[evt] ?? `Claude Code: ${evt}`;
163
+ const title = await (0, prompts_1.input)({
164
+ message: `"${evt}" 事件的通知标题:`,
165
+ default: defaultTitle,
166
+ });
167
+ if (title !== defaultTitle) {
168
+ // AGENTWAKE_CLAUDE_TITLE_STOP, AGENTWAKE_CLAUDE_TITLE_STOP_FAILURE, etc.
169
+ const envKey = `AGENTWAKE_CLAUDE_TITLE_${evt.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toUpperCase()}`;
170
+ eventTitleVars[envKey] = title;
171
+ }
172
+ }
173
+ }
174
+ }
175
+ // Step 3: Select notification channels
176
+ const channels = await (0, prompts_1.checkbox)({
177
+ message: "选择通知渠道(PWA 和桌面通知默认启用)",
178
+ choices: [
179
+ { name: "钉钉 Webhook", value: "dingtalk" },
180
+ { name: "飞书 Webhook", value: "feishu" },
181
+ { name: "企业微信 Webhook", value: "wecom" },
182
+ { name: "PWA 网页推送(已内置,无需配置)", value: "pwa", checked: true, disabled: "默认启用" },
183
+ { name: "桌面系统通知(已内置,无需配置)", value: "desktop", checked: true, disabled: "默认启用" },
184
+ ],
185
+ });
186
+ // Step 4: Collect webhook configs
187
+ const envVars = {};
188
+ if (channels.includes("dingtalk")) {
189
+ const webhook = await (0, prompts_1.input)({
190
+ message: "输入钉钉 Webhook URL:",
191
+ validate: (v) => v.startsWith("https://") || "请输入有效的 HTTPS URL",
192
+ });
193
+ const secret = await (0, prompts_1.password)({
194
+ message: "输入钉钉安全密钥(可选,直接回车跳过):",
195
+ });
196
+ envVars.AGENTWAKE_DINGTALK_WEBHOOK = webhook;
197
+ if (secret)
198
+ envVars.AGENTWAKE_DINGTALK_SECRET = secret;
199
+ }
200
+ if (channels.includes("feishu")) {
201
+ const webhook = await (0, prompts_1.input)({
202
+ message: "输入飞书 Webhook URL:",
203
+ validate: (v) => v.startsWith("https://") || "请输入有效的 HTTPS URL",
204
+ });
205
+ const secret = await (0, prompts_1.password)({
206
+ message: "输入飞书签名校验密钥(可选,直接回车跳过):",
207
+ });
208
+ envVars.AGENTWAKE_FEISHU_WEBHOOK = webhook;
209
+ if (secret)
210
+ envVars.AGENTWAKE_FEISHU_SECRET = secret;
211
+ }
212
+ if (channels.includes("wecom")) {
213
+ const webhook = await (0, prompts_1.input)({
214
+ message: "输入企业微信群机器人 Webhook URL:",
215
+ validate: (v) => v.startsWith("https://qyapi.weixin.qq.com/") || "请输入有效的企业微信 Webhook URL",
216
+ });
217
+ envVars.AGENTWAKE_WECOM_WEBHOOK = webhook;
218
+ }
219
+ // Step 5: Ensure .env exists in ~/.agentwake/
220
+ if (!(0, node_fs_1.existsSync)(envPath)) {
221
+ const exampleSrc = node_path_1.default.join(paths_1.PKG_ROOT, ".env.example");
222
+ if ((0, node_fs_1.existsSync)(exampleSrc)) {
223
+ (0, node_fs_1.copyFileSync)(exampleSrc, envPath);
224
+ }
225
+ console.log(`📄 已创建 ${envPath}`);
226
+ }
227
+ // Merge title vars into envVars
228
+ Object.assign(envVars, eventTitleVars);
229
+ // Write config to .env
230
+ if (Object.keys(envVars).length > 0) {
231
+ writeEnvFile(envPath, envVars);
232
+ console.log(`\n✅ 配置已写入 ${envPath}`);
233
+ }
234
+ // Step 6: Install Claude Code hooks
235
+ if (aiTool === "claude-code" || aiTool === "all") {
236
+ if (selectedEvents.length > 0) {
237
+ const existing = readEnvFile(envPath);
238
+ const httpsEnabled = existing.AGENTWAKE_HTTPS_ENABLED === "1";
239
+ const port = existing.AGENTWAKE_PORT || "3199";
240
+ const protocol = httpsEnabled ? "https" : "http";
241
+ const gatewayUrl = `${protocol}://127.0.0.1:${port}`;
242
+ const installer = new claude_code_installer_1.ClaudeCodeInstaller(gatewayUrl);
243
+ await installer.install(selectedEvents);
244
+ console.log(`✅ Claude Code hooks 已安装 (${selectedEvents.length} 个事件)`);
245
+ console.log(` 脚本路径: ${node_path_1.default.join(node_os_1.default.homedir(), ".agentwake", "hooks", "claude-hook-relay.sh")}`);
246
+ }
247
+ }
248
+ // Step 7: Start server
249
+ const shouldStart = await (0, prompts_1.confirm)({
250
+ message: "是否立即启动服务?",
251
+ default: true,
252
+ });
253
+ if (shouldStart) {
254
+ // Load env and start
255
+ const dotenv = await Promise.resolve().then(() => __importStar(require("dotenv")));
256
+ dotenv.config({ path: envPath });
257
+ // Apply our new env vars too
258
+ for (const [key, value] of Object.entries(envVars)) {
259
+ process.env[key] = value;
260
+ }
261
+ process.env.AGENTWAKE_HTTPS_ENABLED = "1";
262
+ const { runGateway } = await Promise.resolve().then(() => __importStar(require("./run-gateway")));
263
+ await runGateway();
264
+ }
265
+ const localIp = getLocalIp();
266
+ if (localIp) {
267
+ const existing = readEnvFile(envPath);
268
+ const port = existing.AGENTWAKE_PORT || "3199";
269
+ const protocol = existing.AGENTWAKE_HTTPS_ENABLED === "1" ? "https" : "http";
270
+ console.log(`\n📱 手机浏览器打开:${protocol}://${localIp}:${port}`);
271
+ }
272
+ console.log("\n🎉 配置完成!\n");
273
+ }
274
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,MAAM;gBACL,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBACtC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBACrC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBACtC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CACpD,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,MAAM;gBACL,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBACtC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBACrC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBACtC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CACpD,CAAC"}
@@ -1,14 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.logger = void 0;
4
+ const LOG_PRIORITY = {
5
+ debug: 10,
6
+ info: 20,
7
+ warn: 30,
8
+ error: 40,
9
+ };
10
+ function resolveMinLogLevel() {
11
+ const raw = (process.env.AGENTWAKE_LOG_LEVEL || "error").trim().toLowerCase();
12
+ if (raw === "debug" || raw === "info" || raw === "warn" || raw === "error") {
13
+ return raw;
14
+ }
15
+ return "error";
16
+ }
17
+ const MIN_LOG_LEVEL = resolveMinLogLevel();
4
18
  function log(level, msg, meta) {
19
+ if (LOG_PRIORITY[level] < LOG_PRIORITY[MIN_LOG_LEVEL]) {
20
+ return;
21
+ }
5
22
  const ts = new Date().toISOString();
6
23
  const prefix = `[${ts}] [${level.toUpperCase()}]`;
24
+ const writer = level === "error" ? console.error : console.log;
7
25
  if (meta && Object.keys(meta).length > 0) {
8
- console.log(prefix, msg, JSON.stringify(meta));
26
+ writer(prefix, msg, JSON.stringify(meta));
9
27
  return;
10
28
  }
11
- console.log(prefix, msg);
29
+ writer(prefix, msg);
12
30
  }
13
31
  exports.logger = {
14
32
  info: (msg, meta) => log("info", msg, meta),
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;AAEA,SAAS,GAAG,CAAC,KAAe,EAAE,GAAW,EAAE,IAA8B;IACvE,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IAClD,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;IAC7E,IAAI,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;IAC7E,KAAK,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;IAC/E,KAAK,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;CAChF,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;AAEA,MAAM,YAAY,GAA6B;IAC7C,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,SAAS,kBAAkB;IACzB,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9E,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QAC3E,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,aAAa,GAAG,kBAAkB,EAAE,CAAC;AAE3C,SAAS,GAAG,CAAC,KAAe,EAAE,GAAW,EAAE,IAA8B;IACvE,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;QACtD,OAAO;IACT,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;IAC/D,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACtB,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;IAC7E,IAAI,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;IAC7E,KAAK,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;IAC/E,KAAK,EAAE,CAAC,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;CAChF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentwake",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Cross-editor notification gateway for approval waiting events.",
5
5
  "main": "dist/main.js",
6
6
  "files": [
@@ -21,7 +21,8 @@
21
21
  "start": "node dist/cli.js start",
22
22
  "test": "vitest run",
23
23
  "test:watch": "vitest",
24
- "init": "tsx src/cli.ts init"
24
+ "init": "tsx src/cli.ts init",
25
+ "setup": "tsx src/cli.ts setup"
25
26
  },
26
27
  "repository": {
27
28
  "type": "git",
@@ -36,6 +37,7 @@
36
37
  },
37
38
  "homepage": "https://github.com/tjdxwwj/agentwake#readme",
38
39
  "dependencies": {
40
+ "@inquirer/prompts": "^8.4.1",
39
41
  "@types/qrcode-terminal": "^0.12.2",
40
42
  "dotenv": "^17.4.1",
41
43
  "express": "^5.2.1",
@@ -30,6 +30,40 @@ const DANGEROUS_COMMAND_PATTERNS = [
30
30
  /\bcurl\b.*\|\s*(sh|bash|zsh)\b/i,
31
31
  ];
32
32
 
33
+ function isEnabledAgentFlag(name) {
34
+ const raw = String(process.env[name] || "").trim().toLowerCase();
35
+ return raw !== "" && raw !== "0" && raw !== "false" && raw !== "no";
36
+ }
37
+
38
+ function resolveAgentMarkerFromEnv() {
39
+ const cursorAgent = isEnabledAgentFlag("CURSOR_AGRNT") || isEnabledAgentFlag("CURSOR_AGENT");
40
+ const qoderAgent = isEnabledAgentFlag("QODER_AGENT");
41
+ const agentMarker = cursorAgent ? "cursor" : qoderAgent ? "qoder" : undefined;
42
+ return { cursorAgent, qoderAgent, agentMarker };
43
+ }
44
+
45
+ async function resolveParentChildCount() {
46
+ try {
47
+ const { stdout } = await execFileAsync("ps", ["-axo", "ppid=,pid="]);
48
+ const lines = String(stdout || "").split("\n");
49
+ const parentPid = String(process.ppid);
50
+ let count = 0;
51
+ for (const line of lines) {
52
+ const trimmed = line.trim();
53
+ if (!trimmed) {
54
+ continue;
55
+ }
56
+ const [ppid, pid] = trimmed.split(/\s+/);
57
+ if (ppid === parentPid && pid && pid !== String(process.pid)) {
58
+ count += 1;
59
+ }
60
+ }
61
+ return count;
62
+ } catch {
63
+ return undefined;
64
+ }
65
+ }
66
+
33
67
  function shouldAskForDangerousCommand(command) {
34
68
  const text = String(command || "").trim();
35
69
  if (!text) {
@@ -193,15 +227,27 @@ async function main() {
193
227
  if (eventName !== "beforeShellExecution" && eventName !== "afterShellExecution") {
194
228
  return;
195
229
  }
196
- let forwardedPayload = payload;
230
+ const { cursorAgent, qoderAgent, agentMarker } = resolveAgentMarkerFromEnv();
231
+ const parentChildCount = await resolveParentChildCount();
232
+ const hasChildProcess = typeof parentChildCount === "number" ? parentChildCount > 0 : false;
233
+
234
+ let forwardedPayload = {
235
+ ...payload,
236
+ cursor_agent: cursorAgent,
237
+ qoder_agent: qoderAgent,
238
+ ...(agentMarker ? { agent_marker: agentMarker } : {}),
239
+ parent_pid: Number(process.ppid),
240
+ has_child_process: hasChildProcess,
241
+ parent_child_count: typeof parentChildCount === "number" ? parentChildCount : 0,
242
+ };
197
243
  if (eventName === "beforeShellExecution" && enforceDangerousAsk) {
198
- const command = String(payload?.command || "");
244
+ const command = String(forwardedPayload?.command || "");
199
245
  if (shouldAskForDangerousCommand(command)) {
200
246
  const reasonText = `AgentWake risk policy matched: ${command}`;
201
247
  let reply;
202
248
  let approvalDecision = "ask";
203
249
  if (approvalMode === "osascript") {
204
- const cacheKey = resolveApprovalCacheKey(payload);
250
+ const cacheKey = resolveApprovalCacheKey(forwardedPayload);
205
251
  const cachedDecision = readCachedDecision(cacheKey);
206
252
  approvalDecision = cachedDecision || (await resolveOsaDecision(command));
207
253
  if (!cachedDecision) {
@@ -232,7 +278,7 @@ async function main() {
232
278
  }
233
279
  process.stdout.write(`${JSON.stringify(reply)}\n`);
234
280
  forwardedPayload = {
235
- ...payload,
281
+ ...forwardedPayload,
236
282
  permission: reply.permission,
237
283
  pendingApproval: approvalDecision === "ask",
238
284
  reason: reasonText,