@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/doctor.js ADDED
@@ -0,0 +1,326 @@
1
+ import { constants } from "node:fs";
2
+ import { access, stat } from "node:fs/promises";
3
+ import { spawnSync } from "node:child_process";
4
+ import { loadConfig } from "./config.js";
5
+ import { fromRoot, readTextFile } from "./fs.js";
6
+ import { hasGitBaseline, getProjectFiles } from "./git.js";
7
+ import { getHookStatus, hookConfigPaths, claudeHookCommand, codexHookCommand } from "./hooks.js";
8
+ import { detectProject } from "./project-detection.js";
9
+ import { fileExists } from "./project-memory.js";
10
+ import { listRunLogs } from "./runs.js";
11
+ import { readDriftTelemetryStats } from "./drift-telemetry.js";
12
+ import { readRuntimeState } from "./runtime-state.js";
13
+ import { formatStrategyFlag, getAgentStrategyReport } from "./agent-strategies.js";
14
+ import { formatNotifyCommand, getCodexNotifyConfigStatus } from "./codex-notify.js";
15
+ export async function runDoctor(root, args = []) {
16
+ if (args.includes("--agents")) {
17
+ await runAgentDoctor(root);
18
+ return;
19
+ }
20
+ if (args.includes("--hooks")) {
21
+ await runHookDoctor(root, { dryRun: args.includes("--dry-run") });
22
+ return;
23
+ }
24
+ const [resolved, baseline, projectFiles, runs, telemetry, cacheSize, hookStatus, runtime] = await Promise.all([
25
+ loadConfig(root),
26
+ hasGitBaseline(root).catch(() => false),
27
+ getProjectFiles(root).catch(() => []),
28
+ listRunLogs(root),
29
+ readDriftTelemetryStats(root),
30
+ memoryCacheSize(root),
31
+ getHookStatus(root),
32
+ readRuntimeState(root)
33
+ ]);
34
+ const project = await detectProject(root, projectFiles).catch(() => undefined);
35
+ const claudeCommand = await readHookCommand(root, hookConfigPaths.claudeSettingsPath, hookConfigPaths.claudeHookPath).catch(() => undefined);
36
+ const codexCommand = await readHookCommand(root, hookConfigPaths.codexHooksPath, hookConfigPaths.codexHookPath).catch(() => undefined);
37
+ const claudeTarget = resolveHookCommandTarget(root, claudeCommand ?? claudeHookCommand);
38
+ const codexTarget = resolveHookCommandTarget(root, codexCommand ?? codexHookCommand);
39
+ const provider = resolved.config.ai?.provider ?? "none";
40
+ const model = resolved.config.ai?.model ?? "gpt-4o-mini";
41
+ const staleRuns = runs.filter((run) => isStale(run.createdAt)).length;
42
+ const apiKeyFound = provider === "openai" ? resolved.env.apiKey.found : false;
43
+ console.log("dev-guard doctor");
44
+ console.log(`Provider: ${provider}`);
45
+ console.log(`Model: ${model}`);
46
+ console.log(`API Key: ${provider === "openai" ? (apiKeyFound ? "found" : "missing") : "not required"}`);
47
+ console.log(`Config Source: ${resolved.source}`);
48
+ console.log("ENV:");
49
+ console.log(`- DEV_GUARD_OPENAI_API_KEY: ${resolved.env.apiKey.checked[0]?.found ? "found" : "missing"}`);
50
+ console.log(`- OPENAI_API_KEY: ${resolved.env.apiKey.checked[1]?.found ? "found" : "missing"}`);
51
+ console.log(`- selected provider: ${provider}`);
52
+ console.log(`- selected model: ${model}`);
53
+ console.log(`- selected API key source: ${resolved.env.apiKey.selectedKey ?? "none"}`);
54
+ for (const warning of resolved.warnings) {
55
+ console.log(`Config Warning: ${warning}`);
56
+ }
57
+ console.log(`Git Baseline: ${baseline ? "present" : "missing"}`);
58
+ if (!baseline) {
59
+ console.log('Git Baseline Recovery: git add . && git commit -m "initial commit"');
60
+ }
61
+ console.log(`Framework: ${project?.frameworks.join(", ") || "(unknown)"}`);
62
+ console.log(`Language: ${project?.language ?? "(unknown)"}`);
63
+ console.log(`Runtime: ${project?.runtime ?? "(unknown)"}`);
64
+ console.log(`Package Manager: ${project?.packageManager ?? "(unknown)"}`);
65
+ console.log(`Drift Telemetry: enabled (${telemetry.events} stored events)`);
66
+ console.log(`Watch Capability: polling watch available; auto-refresh only by default`);
67
+ console.log(`Local Heuristic Review: available (dev-guard review --heuristic)`);
68
+ console.log(`Local Heuristic Check: available (dev-guard check --local)`);
69
+ console.log(`Memory Runs: ${runs.length}`);
70
+ console.log(`Stale Runs: ${staleRuns}`);
71
+ console.log(`Memory Cache Size: ${cacheSize} bytes`);
72
+ console.log(`Project Memory: ${(await fileExists(root, ".devguard/project-index.json")) ? "present" : "missing"}`);
73
+ console.log("");
74
+ console.log("Hooks:");
75
+ console.log(`- .devguard directory exists: ${await existsPath(root, ".devguard") ? "yes" : "no"}`);
76
+ console.log(`- hook scripts exist: ${hookStatus.claudeHookFile && hookStatus.codexHookFile ? "yes" : "no"}`);
77
+ console.log(`- hook scripts executable: ${(await isExecutable(root, hookConfigPaths.claudeHookPath)) && (await isExecutable(root, hookConfigPaths.codexHookPath)) ? "yes" : "no"}`);
78
+ console.log(`- .claude/settings.json exists: ${hookStatus.claudeInstalled ? "yes" : "no"}`);
79
+ console.log(`- .codex/hooks.json exists: ${hookStatus.codexInstalled ? "yes" : "no"}`);
80
+ console.log(`- Claude hook command path: ${claudeCommand ?? "(not found; expected " + claudeHookCommand + ")"}`);
81
+ console.log(`- Codex hook command path: ${codexCommand ?? "(not found; expected " + codexHookCommand + ")"}`);
82
+ console.log(`- Claude hook command target exists: ${claudeTarget && await existsAbsolutePath(claudeTarget) ? "yes" : "no"}`);
83
+ console.log(`- Codex hook command target exists: ${codexTarget && await existsAbsolutePath(codexTarget) ? "yes" : "no"}`);
84
+ console.log(`- latest hook log exists: ${await latestHookLogExists(root) ? "yes" : "no"}`);
85
+ console.log(`- latest hook trigger time: ${hookStatus.lastTrigger ?? "none"}`);
86
+ console.log(`- latest hook success: ${hookStatus.lastSuccess === undefined ? "unknown" : hookStatus.lastSuccess ? "yes" : "no"}`);
87
+ console.log(`- pending files count: ${runtime.pendingChangedFiles.length}`);
88
+ console.log(`- runtime status: ${runtime.lastStatus ?? "idle"}`);
89
+ console.log(`Next: ${baseline ? "run dev-guard check --local before commit" : "create an initial git commit to reduce noisy untracked output"}`);
90
+ console.log(`Hook Next: ${expectedHookNextStep(hookStatus, runtime.pendingChangedFiles.length, runtime.lastStatus)}`);
91
+ console.log("");
92
+ await printAgentStrategies(root);
93
+ }
94
+ async function runHookDoctor(root, options) {
95
+ const beforeStatus = await getHookStatus(root);
96
+ const runtime = await readRuntimeState(root);
97
+ const claudeCommand = await readHookCommand(root, hookConfigPaths.claudeSettingsPath, hookConfigPaths.claudeHookPath).catch(() => undefined);
98
+ const codexCommand = await readHookCommand(root, hookConfigPaths.codexHooksPath, hookConfigPaths.codexHookPath).catch(() => undefined);
99
+ const claudeTarget = resolveHookCommandTarget(root, claudeCommand ?? claudeHookCommand);
100
+ const codexTarget = resolveHookCommandTarget(root, codexCommand ?? codexHookCommand);
101
+ console.log("dev-guard doctor --hooks");
102
+ if (options.dryRun) {
103
+ console.log("Mode: dry-run (hook scripts are not executed)");
104
+ }
105
+ else {
106
+ console.log("Mode: active");
107
+ console.log("Warning: doctor --hooks directly executes hook scripts; this can run dev-guard done and dev-guard status.");
108
+ }
109
+ console.log("");
110
+ console.log("Files");
111
+ console.log(`.devguard directory exists: ${await existsPath(root, ".devguard") ? "yes" : "no"}`);
112
+ console.log(`Claude hook script exists: ${await existsPath(root, hookConfigPaths.claudeHookPath) ? "yes" : "no"}`);
113
+ console.log(`Codex hook script exists: ${await existsPath(root, hookConfigPaths.codexHookPath) ? "yes" : "no"}`);
114
+ console.log(`Claude hook script executable: ${await isExecutable(root, hookConfigPaths.claudeHookPath) ? "yes" : "no"}`);
115
+ console.log(`Codex hook script executable: ${await isExecutable(root, hookConfigPaths.codexHookPath) ? "yes" : "no"}`);
116
+ console.log(`.claude/settings.json exists: ${await existsPath(root, hookConfigPaths.claudeSettingsPath) ? "yes" : "no"}`);
117
+ console.log(`.codex/hooks.json exists: ${await existsPath(root, hookConfigPaths.codexHooksPath) ? "yes" : "no"}`);
118
+ console.log("");
119
+ console.log("Commands");
120
+ console.log(`Claude hook command path: ${claudeCommand ?? "(not found; expected " + claudeHookCommand + ")"}`);
121
+ console.log(`Codex hook command path: ${codexCommand ?? "(not found; expected " + codexHookCommand + ")"}`);
122
+ console.log(`Claude command target: ${claudeTarget ?? "unparseable"}`);
123
+ console.log(`Codex command target: ${codexTarget ?? "unparseable"}`);
124
+ console.log(`Claude command target exists: ${claudeTarget && await existsAbsolutePath(claudeTarget) ? "yes" : "no"}`);
125
+ console.log(`Codex command target exists: ${codexTarget && await existsAbsolutePath(codexTarget) ? "yes" : "no"}`);
126
+ console.log(`Claude command parseable: ${claudeTarget ? "yes" : "no"}`);
127
+ console.log(`Codex command parseable: ${codexTarget ? "yes" : "no"}`);
128
+ console.log("");
129
+ console.log("Runtime");
130
+ console.log(`latest hook log exists: ${await latestHookLogExists(root) ? "yes" : "no"}`);
131
+ console.log(`latest hook trigger time: ${beforeStatus.lastTrigger ?? "none"}`);
132
+ console.log(`latest hook success: ${beforeStatus.lastSuccess === undefined ? "unknown" : beforeStatus.lastSuccess ? "yes" : "no"}`);
133
+ console.log(`pending files count: ${runtime.pendingChangedFiles.length}`);
134
+ console.log(`runtime status: ${runtime.lastStatus ?? "idle"}`);
135
+ if (!options.dryRun) {
136
+ console.log("");
137
+ console.log("Direct hook execution tests");
138
+ const tests = [
139
+ { label: ".devguard/hooks/claude-stop.sh", path: hookConfigPaths.claudeHookPath },
140
+ { label: "echo '{}' | .devguard/hooks/claude-stop.sh", path: hookConfigPaths.claudeHookPath, input: "{}\n" },
141
+ { label: ".devguard/hooks/codex-stop.sh", path: hookConfigPaths.codexHookPath },
142
+ { label: "echo '{}' | .devguard/hooks/codex-stop.sh", path: hookConfigPaths.codexHookPath, input: "{}\n" }
143
+ ];
144
+ for (const test of tests) {
145
+ const result = runHookScript(root, test.path, test.input);
146
+ console.log(`${test.label}: ${result.ok ? "PASS" : "FAIL"} exit=${result.status ?? "signal"} duration_ms=${result.durationMs}`);
147
+ if (!result.ok && result.error)
148
+ console.log(` ${result.error}`);
149
+ }
150
+ }
151
+ const afterStatus = await getHookStatus(root);
152
+ console.log("");
153
+ console.log("After");
154
+ console.log(`hook log generated: ${await latestHookLogExists(root) ? "yes" : "no"}`);
155
+ console.log(`status Last Hook Trigger: ${afterStatus.lastTrigger ?? "none"}`);
156
+ console.log(`status Last Hook Success: ${afterStatus.lastSuccess === undefined ? "unknown" : afterStatus.lastSuccess ? "yes" : "no"}`);
157
+ console.log("");
158
+ console.log("Expected next step:");
159
+ console.log(expectedHookNextStep(afterStatus, runtime.pendingChangedFiles.length, runtime.lastStatus));
160
+ }
161
+ async function runAgentDoctor(root) {
162
+ console.log("dev-guard doctor --agents");
163
+ await printAgentStrategies(root);
164
+ }
165
+ async function printAgentStrategies(root) {
166
+ const report = await getAgentStrategyReport(root);
167
+ const codexNotify = await getCodexNotifyConfigStatus();
168
+ console.log("Agent Strategies");
169
+ console.log("");
170
+ console.log("Claude Code");
171
+ printStrategy(report.claude);
172
+ console.log("");
173
+ console.log("Codex");
174
+ console.log(`- recommended strategy: ${report.codexNotify.name}`);
175
+ console.log(`- user-level notify configured: ${formatStrategyFlag(codexNotify.notifyConfigured)}`);
176
+ console.log(`- existing notify detected: ${formatStrategyFlag(codexNotify.existingNotifyDetected)}`);
177
+ console.log(`- notify command: ${formatNotifyCommand(codexNotify.notify)}`);
178
+ console.log(`- dispatcher installed: ${formatStrategyFlag(codexNotify.dispatcherInstalled)}`);
179
+ console.log(`- dispatcher configured: ${formatStrategyFlag(codexNotify.notifyIsDispatcher)}`);
180
+ console.log(`- dispatcher path: ${codexNotify.dispatcherPath}`);
181
+ console.log(`- notify available: ${formatStrategyFlag(report.codexNotify.available)}`);
182
+ console.log(`- notify installed: ${formatStrategyFlag(report.codexNotify.installed)}`);
183
+ console.log(`- notify script verified: ${formatStrategyFlag(report.codexNotify.scriptVerified)}`);
184
+ console.log(`- notify runtime verified: ${formatStrategyFlag(report.codexNotify.runtimeVerified)}`);
185
+ console.log(`- stop hook installed: ${formatStrategyFlag(report.codexStopHook.installed)}`);
186
+ console.log(`- stop hook script verified: ${formatStrategyFlag(report.codexStopHook.scriptVerified)}`);
187
+ console.log(`- stop hook requires trust: ${formatStrategyFlag(report.codexStopHook.requiresUserTrust)}`);
188
+ console.log(`- stop hook runtime verified: ${formatStrategyFlag(report.codexStopHook.runtimeVerified)}`);
189
+ console.log(`- jsonl listener installed: ${formatStrategyFlag(report.codexJsonlListener.installed)}`);
190
+ console.log(`- jsonl listener runtime verified: ${formatStrategyFlag(report.codexJsonlListener.runtimeVerified)}`);
191
+ console.log(`- next: ${report.codexNotify.runtimeVerified ? "Codex notify runtime verified." : report.codexNotify.next}`);
192
+ if (!report.codexStopHook.runtimeVerified) {
193
+ console.log(`- stop hook next: ${report.codexStopHook.next}`);
194
+ }
195
+ console.log("");
196
+ console.log("Manual");
197
+ printStrategy(report.manual);
198
+ }
199
+ function printStrategy(strategy) {
200
+ console.log(`- strategy: ${strategy.name}`);
201
+ console.log(`- available: ${formatStrategyFlag(strategy.available)}`);
202
+ console.log(`- installed: ${formatStrategyFlag(strategy.installed)}`);
203
+ console.log(`- script verified: ${formatStrategyFlag(strategy.scriptVerified)}`);
204
+ console.log(`- runtime verified: ${formatStrategyFlag(strategy.runtimeVerified)}`);
205
+ console.log(`- requires user trust: ${formatStrategyFlag(strategy.requiresUserTrust)}`);
206
+ console.log(`- recommended: ${formatStrategyFlag(strategy.recommended)}`);
207
+ console.log(`- next: ${strategy.next}`);
208
+ }
209
+ async function memoryCacheSize(root) {
210
+ const files = [
211
+ ".devguard/project-index.json",
212
+ ".devguard/file-summaries.json",
213
+ ".devguard/project-map.md",
214
+ ".devguard/project-identity.json",
215
+ ".devguard/drift-telemetry.json"
216
+ ];
217
+ const sizes = await Promise.all(files.map(async (file) => {
218
+ try {
219
+ return (await stat(fromRoot(root, file))).size;
220
+ }
221
+ catch {
222
+ return 0;
223
+ }
224
+ }));
225
+ return sizes.reduce((sum, size) => sum + size, 0);
226
+ }
227
+ function isStale(createdAt) {
228
+ const ageDays = (Date.now() - Date.parse(createdAt)) / 86_400_000;
229
+ return Number.isFinite(ageDays) && ageDays > 90;
230
+ }
231
+ async function existsPath(root, path) {
232
+ return existsAbsolutePath(fromRoot(root, path));
233
+ }
234
+ async function existsAbsolutePath(path) {
235
+ try {
236
+ await stat(path);
237
+ return true;
238
+ }
239
+ catch {
240
+ return false;
241
+ }
242
+ }
243
+ async function isExecutable(root, path) {
244
+ try {
245
+ await access(fromRoot(root, path), constants.X_OK);
246
+ return true;
247
+ }
248
+ catch {
249
+ return false;
250
+ }
251
+ }
252
+ async function readHookCommand(root, configPath, hookPath) {
253
+ const text = await readTextFile(fromRoot(root, configPath));
254
+ const parsed = JSON.parse(text || "{}");
255
+ return findHookCommand(parsed, hookPath);
256
+ }
257
+ function findHookCommand(value, hookPath) {
258
+ if (Array.isArray(value)) {
259
+ for (const item of value) {
260
+ const found = findHookCommand(item, hookPath);
261
+ if (found)
262
+ return found;
263
+ }
264
+ return undefined;
265
+ }
266
+ if (typeof value === "object" && value !== null) {
267
+ const obj = value;
268
+ if (typeof obj.command === "string" && obj.command.includes(hookPath)) {
269
+ return obj.command;
270
+ }
271
+ for (const item of Object.values(obj)) {
272
+ const found = findHookCommand(item, hookPath);
273
+ if (found)
274
+ return found;
275
+ }
276
+ }
277
+ return undefined;
278
+ }
279
+ function resolveHookCommandTarget(root, command) {
280
+ let value = command.trim();
281
+ if (!value)
282
+ return undefined;
283
+ value = value.replace(/\$\{CLAUDE_PROJECT_DIR\}/g, root);
284
+ value = value.replace(/\$\(git rev-parse --show-toplevel\)/g, root);
285
+ value = stripMatchingQuotes(value);
286
+ return value.startsWith("/") ? value : undefined;
287
+ }
288
+ function stripMatchingQuotes(value) {
289
+ let next = value.trim();
290
+ while ((next.startsWith('"') && next.endsWith('"')) || (next.startsWith("'") && next.endsWith("'"))) {
291
+ next = next.slice(1, -1).trim();
292
+ }
293
+ return next;
294
+ }
295
+ async function latestHookLogExists(root) {
296
+ return (await existsPath(root, hookConfigPaths.claudeLogPath)) || (await existsPath(root, hookConfigPaths.codexLogPath));
297
+ }
298
+ function runHookScript(root, path, input) {
299
+ const started = Date.now();
300
+ const result = spawnSync(fromRoot(root, path), {
301
+ cwd: root,
302
+ encoding: "utf8",
303
+ input,
304
+ env: { ...process.env, DEV_GUARD_HOOK_SOURCE: "direct_test" },
305
+ timeout: 30_000
306
+ });
307
+ const error = result.error ? result.error.message : [result.stderr, result.stdout].filter(Boolean).join("\n").slice(0, 500);
308
+ return {
309
+ ok: result.status === 0,
310
+ status: result.status,
311
+ durationMs: Date.now() - started,
312
+ error: error || undefined
313
+ };
314
+ }
315
+ function expectedHookNextStep(status, pendingCount, runtimeStatus) {
316
+ const installed = (status.claudeInstalled && status.claudeHookFile) || (status.codexInstalled && status.codexHookFile);
317
+ const verified = status.claudeLastSuccess === true || status.codexLastSuccess === true;
318
+ if (!installed)
319
+ return "Run dev-guard install-hooks, then dev-guard watch.";
320
+ if (!verified)
321
+ return "Hooks are installed but not verified. Run dev-guard doctor --hooks, trust Codex hooks with /hooks if needed, or fallback: dev-guard done.";
322
+ if (pendingCount > 0 || runtimeStatus === "ready_for_done")
323
+ return "Hook scripts are verified. Wait for the agent Stop Hook, or fallback: dev-guard done.";
324
+ return "Hook scripts are verified. Run dev-guard watch before the next agent task.";
325
+ }
326
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DriftResult } from "@dev-guard/core";
2
+ export declare function recordDriftTelemetry(root: string, input: {
3
+ result: DriftResult;
4
+ source: string;
5
+ driftType?: string;
6
+ subtype?: string;
7
+ }): Promise<void>;
8
+ export declare function summarizeDriftTelemetry(root: string): Promise<string[]>;
9
+ export declare function readDriftTelemetryStats(root: string): Promise<{
10
+ events: number;
11
+ topDrift: string[];
12
+ unstableSubtypes: string[];
13
+ }>;
@@ -0,0 +1,64 @@
1
+ import { fromRoot, readJsonFile, writeTextFile } from "./fs.js";
2
+ const telemetryPath = ".devguard/drift-telemetry.json";
3
+ const maxEvents = 100;
4
+ const maxSummaryKeys = 50;
5
+ export async function recordDriftTelemetry(root, input) {
6
+ if (input.result.severity === "low") {
7
+ return;
8
+ }
9
+ const driftType = input.driftType ?? input.result.reasons[0] ?? "semantic_drift";
10
+ const current = await readJsonFile(fromRoot(root, telemetryPath), { events: [], summary: {} });
11
+ const event = {
12
+ driftType,
13
+ severity: input.result.severity,
14
+ source: input.source,
15
+ timestamp: Date.now(),
16
+ subtype: input.subtype
17
+ };
18
+ const events = [event, ...current.events].slice(0, maxEvents);
19
+ const summary = incrementAndTrim(current.summary, driftType);
20
+ const bySource = incrementAndTrim(current.bySource ?? {}, input.source);
21
+ const bySeverity = incrementAndTrim(current.bySeverity ?? {}, input.result.severity);
22
+ const bySubtype = input.subtype ? incrementAndTrim(current.bySubtype ?? {}, input.subtype) : (current.bySubtype ?? {});
23
+ await writeTextFile(fromRoot(root, telemetryPath), `${JSON.stringify({ events, summary, bySource, bySeverity, bySubtype, rotatedAt: Date.now() }, null, 2)}\n`);
24
+ }
25
+ export async function summarizeDriftTelemetry(root) {
26
+ const store = await readJsonFile(fromRoot(root, telemetryPath), { events: [], summary: {} });
27
+ const lines = [
28
+ "Top Drift Sources:",
29
+ ...formatTop(store.summary, "- none"),
30
+ "",
31
+ "Event Sources:",
32
+ ...formatTop(store.bySource ?? {}, "- none"),
33
+ "",
34
+ "Most Unstable Subtypes:",
35
+ ...formatTop(store.bySubtype ?? {}, "- none"),
36
+ "",
37
+ `Stored Events: ${store.events.length}/${maxEvents}`
38
+ ];
39
+ return lines;
40
+ }
41
+ export async function readDriftTelemetryStats(root) {
42
+ const store = await readJsonFile(fromRoot(root, telemetryPath), { events: [], summary: {} });
43
+ return {
44
+ events: store.events.length,
45
+ topDrift: formatTop(store.summary, "none"),
46
+ unstableSubtypes: formatTop(store.bySubtype ?? {}, "none")
47
+ };
48
+ }
49
+ function incrementAndTrim(summary, key) {
50
+ const next = { ...summary, [key]: (summary[key] ?? 0) + 1 };
51
+ return Object.fromEntries(Object.entries(next)
52
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
53
+ .slice(0, maxSummaryKeys));
54
+ }
55
+ function formatTop(summary, empty) {
56
+ const entries = Object.entries(summary)
57
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
58
+ .slice(0, 5);
59
+ if (entries.length === 0) {
60
+ return [empty];
61
+ }
62
+ return entries.map(([type, count]) => `- ${type}: ${count}`);
63
+ }
64
+ //# sourceMappingURL=drift-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-telemetry.js","sourceRoot":"","sources":["../src/drift-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type ChangeFile, type CodeGraphEntry, type DevGuardRunLog, type InferredDiffIntentClusters, type ProjectIdentity, type TaskAnchorFreshnessResult } from "@dev-guard/core";
2
+ import type { GitChanges } from "./git.js";
3
+ export type EffectiveTaskMode = "diff-first" | "diff-first_uncertain" | "task-first" | "task-first_caution";
4
+ export type EffectiveAnchorStatus = "absent" | "stale" | "uncertain" | "fresh";
5
+ export interface EffectiveTaskOptions {
6
+ forceTask?: boolean;
7
+ fromDiff?: boolean;
8
+ noRun?: boolean;
9
+ runId?: string;
10
+ }
11
+ export interface EffectiveTaskContext {
12
+ anchorStatus: EffectiveAnchorStatus;
13
+ mode: EffectiveTaskMode;
14
+ taskMatchScore: number;
15
+ runMatchScore?: number;
16
+ useTaskMarkdown: boolean;
17
+ useRun: boolean;
18
+ effectiveTaskMarkdown: string;
19
+ effectiveRunLog?: DevGuardRunLog;
20
+ inferredTask: InferredDiffIntentClusters;
21
+ reason: string;
22
+ freshness: TaskAnchorFreshnessResult;
23
+ runSelection: EffectiveRunSelection;
24
+ }
25
+ export interface EffectiveRunSelection {
26
+ run?: DevGuardRunLog;
27
+ score?: number;
28
+ mode: "none" | "explicit" | "latest" | "matched";
29
+ warning?: string;
30
+ }
31
+ export declare function resolveEffectiveTaskContext(input: {
32
+ root: string;
33
+ taskMarkdown: string;
34
+ gitChanges: Pick<GitChanges, "diffText" | "changedFiles" | "changeFiles">;
35
+ reviewChangeFiles?: ChangeFile[];
36
+ changedFiles?: string[];
37
+ codeGraph?: CodeGraphEntry[];
38
+ currentIdentity?: ProjectIdentity;
39
+ options?: EffectiveTaskOptions;
40
+ }): Promise<EffectiveTaskContext>;
41
+ export declare function formatEffectiveTaskBasis(context: EffectiveTaskContext): string[];
42
+ export declare function formatEffectiveTaskContext(prefix: string, context: EffectiveTaskContext): string[];
43
+ export declare function formatEffectiveTaskBlock(title: string, context: EffectiveTaskContext): string[];
44
+ export declare function formatEffectiveRunSummary(context: EffectiveTaskContext): string;