@dev-guard/cli 0.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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/agent-strategies.d.ts +23 -0
  4. package/dist/agent-strategies.js +130 -0
  5. package/dist/agent-strategies.js.map +1 -0
  6. package/dist/ai-context.d.ts +10 -0
  7. package/dist/ai-context.js +143 -0
  8. package/dist/ai-context.js.map +1 -0
  9. package/dist/check.d.ts +6 -0
  10. package/dist/check.js +89 -0
  11. package/dist/check.js.map +1 -0
  12. package/dist/clipboard.d.ts +6 -0
  13. package/dist/clipboard.js +43 -0
  14. package/dist/clipboard.js.map +1 -0
  15. package/dist/codex-notify.d.ts +23 -0
  16. package/dist/codex-notify.js +146 -0
  17. package/dist/codex-notify.js.map +1 -0
  18. package/dist/command-targets.d.ts +10 -0
  19. package/dist/command-targets.js +124 -0
  20. package/dist/command-targets.js.map +1 -0
  21. package/dist/config.d.ts +22 -0
  22. package/dist/config.js +180 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/configure.d.ts +1 -0
  25. package/dist/configure.js +79 -0
  26. package/dist/configure.js.map +1 -0
  27. package/dist/doctor.d.ts +1 -0
  28. package/dist/doctor.js +326 -0
  29. package/dist/doctor.js.map +1 -0
  30. package/dist/drift-telemetry.d.ts +13 -0
  31. package/dist/drift-telemetry.js +64 -0
  32. package/dist/drift-telemetry.js.map +1 -0
  33. package/dist/effective-task.d.ts +44 -0
  34. package/dist/effective-task.js +355 -0
  35. package/dist/effective-task.js.map +1 -0
  36. package/dist/fs.d.ts +10 -0
  37. package/dist/fs.js +58 -0
  38. package/dist/fs.js.map +1 -0
  39. package/dist/git.d.ts +24 -0
  40. package/dist/git.js +235 -0
  41. package/dist/git.js.map +1 -0
  42. package/dist/hooks.d.ts +39 -0
  43. package/dist/hooks.js +513 -0
  44. package/dist/hooks.js.map +1 -0
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +555 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/infer-task.d.ts +1 -0
  49. package/dist/infer-task.js +120 -0
  50. package/dist/infer-task.js.map +1 -0
  51. package/dist/init.d.ts +1 -0
  52. package/dist/init.js +50 -0
  53. package/dist/init.js.map +1 -0
  54. package/dist/install-agent-instructions.d.ts +1 -0
  55. package/dist/install-agent-instructions.js +113 -0
  56. package/dist/install-agent-instructions.js.map +1 -0
  57. package/dist/migration.d.ts +8 -0
  58. package/dist/migration.js +43 -0
  59. package/dist/migration.js.map +1 -0
  60. package/dist/paths.d.ts +38 -0
  61. package/dist/paths.js +41 -0
  62. package/dist/paths.js.map +1 -0
  63. package/dist/project-detection.d.ts +10 -0
  64. package/dist/project-detection.js +144 -0
  65. package/dist/project-detection.js.map +1 -0
  66. package/dist/project-identity.d.ts +7 -0
  67. package/dist/project-identity.js +93 -0
  68. package/dist/project-identity.js.map +1 -0
  69. package/dist/project-memory.d.ts +4 -0
  70. package/dist/project-memory.js +32 -0
  71. package/dist/project-memory.js.map +1 -0
  72. package/dist/prompt.d.ts +13 -0
  73. package/dist/prompt.js +125 -0
  74. package/dist/prompt.js.map +1 -0
  75. package/dist/refresh.d.ts +15 -0
  76. package/dist/refresh.js +146 -0
  77. package/dist/refresh.js.map +1 -0
  78. package/dist/report.d.ts +1 -0
  79. package/dist/report.js +109 -0
  80. package/dist/report.js.map +1 -0
  81. package/dist/review.d.ts +2 -0
  82. package/dist/review.js +653 -0
  83. package/dist/review.js.map +1 -0
  84. package/dist/rule-filter.d.ts +8 -0
  85. package/dist/rule-filter.js +79 -0
  86. package/dist/rule-filter.js.map +1 -0
  87. package/dist/runs.d.ts +21 -0
  88. package/dist/runs.js +142 -0
  89. package/dist/runs.js.map +1 -0
  90. package/dist/runtime-state.d.ts +69 -0
  91. package/dist/runtime-state.js +1383 -0
  92. package/dist/runtime-state.js.map +1 -0
  93. package/dist/scan.d.ts +1 -0
  94. package/dist/scan.js +55 -0
  95. package/dist/scan.js.map +1 -0
  96. package/dist/self.d.ts +3 -0
  97. package/dist/self.js +235 -0
  98. package/dist/self.js.map +1 -0
  99. package/dist/task-ai.d.ts +1 -0
  100. package/dist/task-ai.js +643 -0
  101. package/dist/task-ai.js.map +1 -0
  102. package/dist/telemetry.d.ts +1 -0
  103. package/dist/telemetry.js +11 -0
  104. package/dist/telemetry.js.map +1 -0
  105. package/dist/update.d.ts +6 -0
  106. package/dist/update.js +154 -0
  107. package/dist/update.js.map +1 -0
  108. package/dist/watch.d.ts +1 -0
  109. package/dist/watch.js +303 -0
  110. package/dist/watch.js.map +1 -0
  111. package/package.json +31 -0
package/dist/hooks.js ADDED
@@ -0,0 +1,513 @@
1
+ import { chmod, mkdir } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ import { spawnSync } from "node:child_process";
5
+ import { fromRoot, readTextFile, writeTextFile } from "./fs.js";
6
+ import { migrateLegacyDevguardDir } from "./migration.js";
7
+ import { devguardPaths } from "./paths.js";
8
+ import { formatNotifyCommand, getCodexNotifyConfigStatus, installCodexNotifyDispatcher } from "./codex-notify.js";
9
+ const claudeHookPath = devguardPaths.claudeHook;
10
+ const codexHookPath = devguardPaths.codexHook;
11
+ const codexNotifyHookPath = devguardPaths.codexNotifyHook;
12
+ const codexListenerPath = devguardPaths.codexEventListener;
13
+ const claudeSettingsPath = ".claude/settings.json";
14
+ const codexHooksPath = ".codex/hooks.json";
15
+ const hookStatusPath = devguardPaths.hookStatus;
16
+ const claudeLogPath = devguardPaths.claudeLog;
17
+ const codexLogPath = devguardPaths.codexLog;
18
+ const codexNotifyLogPath = devguardPaths.codexNotifyLog;
19
+ export const claudeHookCommand = '${CLAUDE_PROJECT_DIR}/.devguard/hooks/claude-stop.sh';
20
+ export const codexHookCommand = '"$(git rev-parse --show-toplevel)/.devguard/hooks/codex-stop.sh"';
21
+ export const hookConfigPaths = {
22
+ claudeSettingsPath,
23
+ codexHooksPath,
24
+ claudeHookPath,
25
+ codexHookPath,
26
+ codexNotifyHookPath,
27
+ claudeLogPath,
28
+ codexLogPath,
29
+ codexNotifyLogPath
30
+ };
31
+ export async function runInstallHooks(root, args) {
32
+ const force = args.includes("--force");
33
+ const installDispatcher = args.includes("--install-dispatcher");
34
+ const agent = readAgentOption(args);
35
+ const result = await installHooks(root, { force, agent, installDispatcher });
36
+ console.log("dev-guard install-hooks");
37
+ console.log(`agent: ${agent}`);
38
+ if (result.created.length > 0) {
39
+ console.log("created:");
40
+ for (const file of result.created)
41
+ console.log(`- ${file}`);
42
+ }
43
+ if (result.skipped.length > 0) {
44
+ console.log("skipped:");
45
+ for (const file of result.skipped)
46
+ console.log(`- ${file}`);
47
+ }
48
+ console.log(`report: ${result.reportPath}`);
49
+ }
50
+ export async function installHooks(root, options = {}) {
51
+ const migration = await migrateLegacyDevguardDir(root, { force: options.force });
52
+ const created = [];
53
+ const skipped = migration.message ? [migration.message] : [];
54
+ const agent = options.agent ?? "auto";
55
+ const installClaude = agent === "all" || agent === "claude" || (agent === "auto" && commandAvailable("claude"));
56
+ const installCodexStopHook = agent === "all" || agent === "codex" || agent === "auto";
57
+ const installCodexNotify = agent === "all" || agent === "codex-notify" || agent === "codex" || agent === "auto";
58
+ const files = [
59
+ ...(installClaude ? [{ path: claudeHookPath, content: shellHook("claude", claudeLogPath), executable: true }] : []),
60
+ ...(installCodexStopHook ? [{ path: codexHookPath, content: shellHook("codex", codexLogPath), executable: true }] : []),
61
+ ...(installCodexNotify ? [{ path: codexNotifyHookPath, content: codexNotifyHook(), executable: true }] : []),
62
+ ...(installCodexStopHook ? [{ path: codexListenerPath, content: codexEventListener(), executable: true }] : [])
63
+ ];
64
+ for (const file of files) {
65
+ const absolute = fromRoot(root, file.path);
66
+ if (existsSync(absolute) && !options.force) {
67
+ skipped.push(`${file.path} (exists; use --force to overwrite)`);
68
+ continue;
69
+ }
70
+ try {
71
+ await writeTextFile(absolute, file.content);
72
+ if (file.executable) {
73
+ await chmod(absolute, 0o755);
74
+ }
75
+ created.push(file.path);
76
+ }
77
+ catch (error) {
78
+ skipped.push(`${file.path} (${errorMessage(error)})`);
79
+ }
80
+ }
81
+ if (installClaude) {
82
+ await installJsonHookConfig(root, claudeSettingsPath, createClaudeHookConfig, { ...options, mergeExisting: true }, created, skipped);
83
+ }
84
+ else if (agent === "auto") {
85
+ skipped.push("Claude Code Stop Hook (claude command not detected; run dev-guard install-hooks --agent claude to force)");
86
+ }
87
+ if (installCodexStopHook) {
88
+ await installJsonHookConfig(root, codexHooksPath, createCodexHookConfig, { ...options, mergeExisting: false }, created, skipped);
89
+ }
90
+ if (installCodexNotify) {
91
+ const notifyStatus = await getCodexNotifyConfigStatus();
92
+ if (options.force || options.installDispatcher) {
93
+ try {
94
+ const dispatcher = await installCodexNotifyDispatcher({ force: options.force });
95
+ if (dispatcher.changed) {
96
+ created.push(dispatcher.dispatcherPath);
97
+ }
98
+ if (dispatcher.backupPath)
99
+ created.push(`${dispatcher.backupPath} (backup)`);
100
+ skipped.push(dispatcher.message);
101
+ }
102
+ catch (error) {
103
+ skipped.push(`Codex notify dispatcher install failed (${errorMessage(error)})`);
104
+ }
105
+ }
106
+ else if (notifyStatus.notifyIsDispatcher) {
107
+ skipped.push("Codex notify dispatcher already configured in ~/.codex/config.toml");
108
+ }
109
+ else if (notifyStatus.existingNotifyDetected) {
110
+ skipped.push(`Existing Codex notify detected: ${formatNotifyCommand(notifyStatus.notify)}`);
111
+ skipped.push("Run dev-guard install-hooks --agent codex-notify --install-dispatcher to preserve it through ~/.codex/dev-guard-notify-dispatcher.sh");
112
+ }
113
+ else {
114
+ skipped.push("Codex notify config is user-level only; run dev-guard install-hooks --agent codex-notify --install-dispatcher to configure ~/.codex/config.toml");
115
+ }
116
+ }
117
+ await writeHookStatusReport(root);
118
+ return { created, skipped, reportPath: hookStatusPath };
119
+ }
120
+ export async function getHookStatus(root) {
121
+ const [claudeLog, codexLog, codexNotifyLog] = await Promise.all([
122
+ readTextFile(fromRoot(root, claudeLogPath)),
123
+ readTextFile(fromRoot(root, codexLogPath)),
124
+ readTextFile(fromRoot(root, codexNotifyLogPath))
125
+ ]);
126
+ const logLines = [...claudeLog.split(/\r?\n/), ...codexLog.split(/\r?\n/), ...codexNotifyLog.split(/\r?\n/)].filter(Boolean);
127
+ const claudeLastLine = latestFinalHookLine(claudeLog.split(/\r?\n/).filter(Boolean));
128
+ const codexLastLine = latestFinalHookLine([...codexLog.split(/\r?\n/), ...codexNotifyLog.split(/\r?\n/)].filter(Boolean));
129
+ const finalLines = logLines.filter(isFinalHookLine);
130
+ const lastLine = latestTimestampedLine(finalLines) ?? latestTimestampedLine(logLines);
131
+ return {
132
+ claudeInstalled: existsSync(fromRoot(root, claudeSettingsPath)),
133
+ codexInstalled: existsSync(fromRoot(root, codexHooksPath)),
134
+ claudeHookFile: existsSync(fromRoot(root, claudeHookPath)),
135
+ codexHookFile: existsSync(fromRoot(root, codexHookPath)),
136
+ lastTrigger: lastLine ? extractLogValue(lastLine, "timestamp") : undefined,
137
+ lastSuccess: lastLine ? extractLogValue(lastLine, "status") === "success" : undefined,
138
+ claudeLastTrigger: claudeLastLine ? extractLogValue(claudeLastLine, "timestamp") : undefined,
139
+ claudeLastSuccess: claudeLastLine ? extractLogValue(claudeLastLine, "status") === "success" : undefined,
140
+ codexLastTrigger: codexLastLine ? extractLogValue(codexLastLine, "timestamp") : undefined,
141
+ codexLastSuccess: codexLastLine ? extractLogValue(codexLastLine, "status") === "success" : undefined
142
+ };
143
+ }
144
+ function codexNotifyHook() {
145
+ return `#!/usr/bin/env bash
146
+ set +e
147
+
148
+ ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
149
+ LOG="$ROOT/${devguardPaths.codexNotifyLog}"
150
+ mkdir -p "$(dirname "$LOG")" "$ROOT/${devguardPaths.reportsDir}"
151
+
152
+ payload="$1"
153
+ if [ -z "$payload" ]; then
154
+ if IFS= read -r -t 1 line || [ -n "$line" ]; then
155
+ payload="$line"
156
+ else
157
+ payload="{}"
158
+ fi
159
+ fi
160
+
161
+ timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
162
+ hook_source="\${DEV_GUARD_HOOK_SOURCE:-agent_runtime}"
163
+ event_type="$(printf '%s\\n' "$payload" | sed -n 's/.*"type"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | head -n 1)"
164
+ if [ -z "$event_type" ]; then
165
+ event_type="$(printf '%s\\n' "$payload" | sed -n 's/.*"event"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | head -n 1)"
166
+ fi
167
+ if [ -z "$event_type" ]; then
168
+ event_type="unknown"
169
+ fi
170
+
171
+ {
172
+ echo "timestamp=$timestamp hook=codex.notify status=start source=$hook_source event=$event_type"
173
+ echo "timestamp=$timestamp hook=codex.notify payload_begin"
174
+ printf '%s\\n' "$payload"
175
+ echo "timestamp=$timestamp hook=codex.notify payload_end"
176
+ if [ "$event_type" != "agent-turn-complete" ]; then
177
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify status=skipped source=$hook_source event=$event_type reason=not_agent_turn_complete"
178
+ exit 0
179
+ fi
180
+ cd "$ROOT" || exit 1
181
+ if [ -f package.json ] && grep -q '"cli"' package.json; then
182
+ if command -v pnpm >/dev/null 2>&1; then
183
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify command=pnpm_cli_done status=running"
184
+ pnpm cli done
185
+ done_status=$?
186
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify command=pnpm_cli_done status=completed exit=$done_status"
187
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify command=pnpm_cli_status status=running"
188
+ pnpm cli status
189
+ status_status=$?
190
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify command=pnpm_cli_status status=completed exit=$status_status"
191
+ else
192
+ echo "dev-guard Codex notify failed: pnpm was not found. Install pnpm or run dev-guard done/status manually."
193
+ done_status=127
194
+ status_status=127
195
+ fi
196
+ else
197
+ if command -v dev-guard >/dev/null 2>&1; then
198
+ dev-guard done
199
+ done_status=$?
200
+ dev-guard status
201
+ status_status=$?
202
+ else
203
+ echo "dev-guard Codex notify failed: dev-guard was not found on PATH."
204
+ done_status=127
205
+ status_status=127
206
+ fi
207
+ fi
208
+ if [ "$done_status" -eq 0 ] && [ "$status_status" -eq 0 ]; then
209
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify status=success source=$hook_source done=$done_status status_cmd=$status_status"
210
+ else
211
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=codex.notify status=failed source=$hook_source done=$done_status status_cmd=$status_status"
212
+ fi
213
+ } >> "$LOG" 2>&1
214
+
215
+ exit 0
216
+ `;
217
+ }
218
+ export async function writeHookStatusReport(root) {
219
+ await mkdir(dirname(fromRoot(root, hookStatusPath)), { recursive: true });
220
+ const status = await getHookStatus(root);
221
+ const markdown = [
222
+ "# Hook Status",
223
+ "",
224
+ "## Installed",
225
+ `- Claude Code: ${status.claudeInstalled && status.claudeHookFile ? "INSTALLED" : "NOT_INSTALLED"} / ${status.claudeLastSuccess ? "VERIFIED" : "NOT_VERIFIED"}`,
226
+ `- Codex CLI: ${status.codexInstalled && status.codexHookFile ? "INSTALLED" : "NOT_INSTALLED"} / ${status.codexLastSuccess ? "VERIFIED" : "NOT_VERIFIED"}`,
227
+ "",
228
+ "## Files",
229
+ `- ${claudeHookPath}: ${status.claudeHookFile ? "exists" : "missing"}`,
230
+ `- ${codexHookPath}: ${status.codexHookFile ? "exists" : "missing"}`,
231
+ `- ${claudeSettingsPath}: ${status.claudeInstalled ? "exists" : "missing"}`,
232
+ `- ${codexHooksPath}: ${status.codexInstalled ? "exists" : "missing"}`,
233
+ "",
234
+ "## Last Hook Trigger",
235
+ `- time: ${status.lastTrigger ?? "none"}`,
236
+ `- success: ${status.lastSuccess === undefined ? "unknown" : status.lastSuccess ? "yes" : "no"}`,
237
+ `- Claude Code time: ${status.claudeLastTrigger ?? "none"}`,
238
+ `- Codex CLI time: ${status.codexLastTrigger ?? "none"}`
239
+ ].join("\n") + "\n";
240
+ await writeTextFile(fromRoot(root, hookStatusPath), markdown);
241
+ return hookStatusPath;
242
+ }
243
+ function shellHook(kind, logPath) {
244
+ return `#!/usr/bin/env bash
245
+ set +e
246
+
247
+ ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
248
+ LOG="$ROOT/${logPath}"
249
+ mkdir -p "$(dirname "$LOG")" "$ROOT/${devguardPaths.reportsDir}"
250
+
251
+ read_hook_input() {
252
+ local line=""
253
+ if IFS= read -r -t 1 line || [ -n "$line" ]; then
254
+ hook_input="$line"
255
+ else
256
+ hook_input=""
257
+ fi
258
+ }
259
+
260
+ hook_input=""
261
+ read_hook_input
262
+ if [ -z "$hook_input" ]; then
263
+ hook_input="{}"
264
+ hook_input_state="empty_or_timeout"
265
+ else
266
+ hook_input_state="present"
267
+ fi
268
+ timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
269
+ hook_source="\${DEV_GUARD_HOOK_SOURCE:-agent_runtime}"
270
+ {
271
+ echo "timestamp=$timestamp hook=${kind}.stop status=start source=$hook_source"
272
+ if [ "$hook_input_state" = "empty_or_timeout" ]; then
273
+ echo "timestamp=$timestamp hook=${kind}.stop stdin=empty_or_timeout"
274
+ else
275
+ echo "timestamp=$timestamp hook=${kind}.stop stdin_json_begin"
276
+ printf '%s\\n' "$hook_input"
277
+ echo "timestamp=$timestamp hook=${kind}.stop stdin_json_end"
278
+ fi
279
+ cd "$ROOT" || exit 1
280
+ if [ -f package.json ] && grep -q '"cli"' package.json; then
281
+ if command -v pnpm >/dev/null 2>&1; then
282
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=pnpm_cli_done status=running"
283
+ pnpm cli done
284
+ done_status=$?
285
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=pnpm_cli_done status=completed exit=$done_status"
286
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=pnpm_cli_status status=running"
287
+ pnpm cli status
288
+ status_status=$?
289
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=pnpm_cli_status status=completed exit=$status_status"
290
+ else
291
+ echo "dev-guard hook failed: pnpm was not found. Install pnpm or run dev-guard done/status manually."
292
+ done_status=127
293
+ status_status=127
294
+ fi
295
+ else
296
+ if command -v dev-guard >/dev/null 2>&1; then
297
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=dev-guard_done status=running"
298
+ dev-guard done
299
+ done_status=$?
300
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=dev-guard_done status=completed exit=$done_status"
301
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=dev-guard_status status=running"
302
+ dev-guard status
303
+ status_status=$?
304
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop command=dev-guard_status status=completed exit=$status_status"
305
+ else
306
+ echo "dev-guard hook failed: dev-guard was not found on PATH. Install/link dev-guard or run the local CLI manually."
307
+ done_status=127
308
+ status_status=127
309
+ fi
310
+ fi
311
+ if [ "$done_status" -eq 0 ] && [ "$status_status" -eq 0 ]; then
312
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop status=success source=$hook_source done=$done_status status_cmd=$status_status"
313
+ else
314
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop status=failed source=$hook_source done=$done_status status_cmd=$status_status"
315
+ if [ "$done_status" -ne 0 ]; then
316
+ echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") hook=${kind}.stop handoff=not_generated reason=done_failed"
317
+ fi
318
+ fi
319
+ } >> "$LOG" 2>&1
320
+
321
+ {
322
+ printf '# Hook Status\\n\\n'
323
+ printf '## Installed\\n'
324
+ printf -- '- Claude Code: %s\\n' "$([ -f "$ROOT/${claudeSettingsPath}" ] && [ -f "$ROOT/${claudeHookPath}" ] && echo INSTALLED || echo NOT_INSTALLED)"
325
+ printf -- '- Codex CLI: %s\\n\\n' "$([ -f "$ROOT/${codexHooksPath}" ] && [ -f "$ROOT/${codexHookPath}" ] && echo INSTALLED || echo NOT_INSTALLED)"
326
+ printf '## Files\\n'
327
+ printf -- '- ${claudeHookPath}: %s\\n' "$([ -f "$ROOT/${claudeHookPath}" ] && echo exists || echo missing)"
328
+ printf -- '- ${codexHookPath}: %s\\n' "$([ -f "$ROOT/${codexHookPath}" ] && echo exists || echo missing)"
329
+ printf -- '- ${claudeSettingsPath}: %s\\n' "$([ -f "$ROOT/${claudeSettingsPath}" ] && echo exists || echo missing)"
330
+ printf -- '- ${codexHooksPath}: %s\\n\\n' "$([ -f "$ROOT/${codexHooksPath}" ] && echo exists || echo missing)"
331
+ printf '## Last Hook Trigger\\n'
332
+ printf -- '- time: %s\\n' "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
333
+ printf -- '- success: %s\\n' "$([ "$done_status" -eq 0 ] && [ "$status_status" -eq 0 ] && echo yes || echo no)"
334
+ } > "$ROOT/${devguardPaths.hookStatus}"
335
+
336
+ if [ "${kind}" = "codex" ]; then
337
+ printf '{}\\n'
338
+ fi
339
+
340
+ exit 0
341
+ `;
342
+ }
343
+ function codexEventListener() {
344
+ return `#!/usr/bin/env node
345
+ const { spawnSync } = require("node:child_process");
346
+ const { appendFileSync, mkdirSync } = require("node:fs");
347
+ const { dirname, resolve } = require("node:path");
348
+
349
+ const root = resolve(__dirname, "../..");
350
+ const logPath = resolve(root, "${devguardPaths.codexLog}");
351
+ mkdirSync(dirname(logPath), { recursive: true });
352
+
353
+ let input = "";
354
+ process.stdin.setEncoding("utf8");
355
+ process.stdin.on("data", (chunk) => {
356
+ input += chunk;
357
+ });
358
+ process.stdin.on("end", () => {
359
+ const lines = input.split(/\\r?\\n/).filter(Boolean);
360
+ for (const line of lines) {
361
+ let event;
362
+ try {
363
+ event = JSON.parse(line);
364
+ } catch {
365
+ continue;
366
+ }
367
+ const type = event.type || event.event || event.name;
368
+ if (type !== "turn.completed" && type !== "turn.failed") continue;
369
+ appendFileSync(logPath, "timestamp=" + new Date().toISOString() + " hook=codex." + type + " status=start\\n");
370
+ if (type === "turn.completed") {
371
+ if (spawnSync("pnpm", ["--version"], { cwd: root, encoding: "utf8" }).status !== 0) {
372
+ appendFileSync(logPath, "dev-guard codex JSONL listener failed: pnpm was not found. Install pnpm or run dev-guard done/status manually.\\n");
373
+ appendFileSync(logPath, "timestamp=" + new Date().toISOString() + " hook=codex." + type + " status=failed done=127 status_cmd=127\\n");
374
+ continue;
375
+ }
376
+ const done = spawnSync("pnpm", ["cli", "done"], { cwd: root, encoding: "utf8" });
377
+ const status = spawnSync("pnpm", ["cli", "status"], { cwd: root, encoding: "utf8" });
378
+ appendFileSync(logPath, done.stdout + done.stderr + status.stdout + status.stderr);
379
+ appendFileSync(logPath, "timestamp=" + new Date().toISOString() + " hook=codex." + type + " status=" + (done.status === 0 && status.status === 0 ? "success" : "failed") + " done=" + done.status + " status_cmd=" + status.status + "\\n");
380
+ } else {
381
+ appendFileSync(logPath, "timestamp=" + new Date().toISOString() + " hook=codex." + type + " status=skipped_failed_turn\\n");
382
+ }
383
+ }
384
+ });
385
+ `;
386
+ }
387
+ async function installJsonHookConfig(root, path, createConfig, options, created, skipped) {
388
+ const absolute = fromRoot(root, path);
389
+ const existed = existsSync(absolute);
390
+ let current = {};
391
+ if (existed) {
392
+ if (!options.force && !options.mergeExisting) {
393
+ skipped.push(`${path} (exists; use --force to update)`);
394
+ return;
395
+ }
396
+ const text = await readTextFile(absolute);
397
+ try {
398
+ current = parseJsonObject(text, path);
399
+ }
400
+ catch (error) {
401
+ if (!options.force) {
402
+ skipped.push(`${path} (${errorMessage(error)}; use --force to overwrite)`);
403
+ return;
404
+ }
405
+ current = {};
406
+ }
407
+ }
408
+ const next = createConfig(current);
409
+ const changed = JSON.stringify(current) !== JSON.stringify(next);
410
+ if (!changed && existed) {
411
+ skipped.push(`${path} (dev-guard hook already installed)`);
412
+ return;
413
+ }
414
+ await writeTextFile(absolute, `${JSON.stringify(next, null, 2)}\n`);
415
+ created.push(existed ? `${path} (updated)` : path);
416
+ }
417
+ function createClaudeHookConfig(current) {
418
+ return addCommandHook(current, "Stop", {
419
+ type: "command",
420
+ command: claudeHookCommand,
421
+ statusMessage: "Running dev-guard done/status"
422
+ });
423
+ }
424
+ function createCodexHookConfig(current) {
425
+ return addCommandHook(current, "Stop", {
426
+ type: "command",
427
+ command: codexHookCommand,
428
+ timeout: 600,
429
+ statusMessage: "Running dev-guard done/status"
430
+ });
431
+ }
432
+ function addCommandHook(current, event, handler) {
433
+ const next = cloneJsonObject(current);
434
+ const hooks = isJsonObject(next.hooks) ? next.hooks : {};
435
+ const hookPath = typeof handler.command === "string" ? handler.command.replace(/^\$\{CLAUDE_PROJECT_DIR\}\//, "").replace(/^"?\$\(git rev-parse --show-toplevel\)\//, "").replace(/"$/, "") : "";
436
+ const legacyHookPath = hookPath.replace(/^\.devguard\//, "devguard/");
437
+ const groups = (Array.isArray(hooks[event]) ? hooks[event] : [])
438
+ .filter(isJsonObject)
439
+ .map((item) => {
440
+ const handlers = Array.isArray(item.hooks)
441
+ ? item.hooks.filter((candidate) => {
442
+ if (!isJsonObject(candidate))
443
+ return true;
444
+ return typeof candidate.command !== "string" || (!candidate.command.includes(hookPath) && !candidate.command.includes(legacyHookPath)) || candidate.command === handler.command;
445
+ })
446
+ : [];
447
+ return { ...item, hooks: handlers };
448
+ })
449
+ .filter((item) => Array.isArray(item.hooks) && item.hooks.length > 0);
450
+ const group = (groups.find((item) => !("matcher" in item) && Array.isArray(item.hooks)) ?? groups.find((item) => isJsonObject(item) && Array.isArray(item.hooks)));
451
+ if (group) {
452
+ if (event === "Stop" && group.matcher === "") {
453
+ delete group.matcher;
454
+ }
455
+ const handlers = Array.isArray(group.hooks) ? [...group.hooks] : [];
456
+ if (!handlers.some((item) => isJsonObject(item) && item.command === handler.command)) {
457
+ group.hooks = [...handlers, handler];
458
+ }
459
+ }
460
+ else {
461
+ groups.push({ hooks: [handler] });
462
+ }
463
+ hooks[event] = groups;
464
+ next.hooks = hooks;
465
+ return next;
466
+ }
467
+ function parseJsonObject(text, path) {
468
+ const parsed = text.trim() ? JSON.parse(text) : {};
469
+ if (!isJsonObject(parsed)) {
470
+ throw new Error(`${path} is not a JSON object`);
471
+ }
472
+ return parsed;
473
+ }
474
+ function cloneJsonObject(value) {
475
+ return JSON.parse(JSON.stringify(value));
476
+ }
477
+ function isJsonObject(value) {
478
+ return typeof value === "object" && value !== null && !Array.isArray(value);
479
+ }
480
+ function extractLogValue(line, key) {
481
+ const match = new RegExp(`${key}=([^\\s]+)`).exec(line);
482
+ return match?.[1];
483
+ }
484
+ function latestTimestampedLine(lines) {
485
+ return lines
486
+ .map((line) => ({ line, timestamp: extractLogValue(line, "timestamp") }))
487
+ .filter((entry) => Boolean(entry.timestamp))
488
+ .sort((a, b) => a.timestamp.localeCompare(b.timestamp))
489
+ .at(-1)?.line;
490
+ }
491
+ function latestFinalHookLine(lines) {
492
+ return latestTimestampedLine(lines.filter(isFinalHookLine));
493
+ }
494
+ function isFinalHookLine(line) {
495
+ return /hook=[a-z]+\.(stop|notify) status=(success|failed)\b/.test(line);
496
+ }
497
+ function errorMessage(error) {
498
+ return error instanceof Error ? error.message : String(error);
499
+ }
500
+ function readAgentOption(args) {
501
+ const index = args.indexOf("--agent");
502
+ if (index < 0)
503
+ return "auto";
504
+ const value = args[index + 1];
505
+ if (value === "claude" || value === "codex" || value === "codex-notify" || value === "all") {
506
+ return value;
507
+ }
508
+ throw new Error("--agent must be one of claude, codex, codex-notify, all.");
509
+ }
510
+ function commandAvailable(command) {
511
+ return spawnSync("sh", ["-c", `command -v ${command}`], { encoding: "utf8" }).status === 0;
512
+ }
513
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};