@viewportai/daemon 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.
- package/LICENSE +176 -0
- package/README.md +157 -0
- package/bin/vpd.js +3 -0
- package/dist/adapters/claude.d.ts +119 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +621 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex-event-normalizers.d.ts +10 -0
- package/dist/adapters/codex-event-normalizers.d.ts.map +1 -0
- package/dist/adapters/codex-event-normalizers.js +208 -0
- package/dist/adapters/codex-event-normalizers.js.map +1 -0
- package/dist/adapters/codex-sdk-loader.d.ts +47 -0
- package/dist/adapters/codex-sdk-loader.d.ts.map +1 -0
- package/dist/adapters/codex-sdk-loader.js +19 -0
- package/dist/adapters/codex-sdk-loader.js.map +1 -0
- package/dist/adapters/codex.d.ts +56 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +267 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/gemini-cli.d.ts +49 -0
- package/dist/adapters/gemini-cli.d.ts.map +1 -0
- package/dist/adapters/gemini-cli.js +181 -0
- package/dist/adapters/gemini-cli.js.map +1 -0
- package/dist/adapters/pty.d.ts +56 -0
- package/dist/adapters/pty.d.ts.map +1 -0
- package/dist/adapters/pty.js +223 -0
- package/dist/adapters/pty.js.map +1 -0
- package/dist/agents/aider.d.ts +9 -0
- package/dist/agents/aider.d.ts.map +1 -0
- package/dist/agents/aider.js +37 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/built-in.d.ts +4 -0
- package/dist/agents/built-in.d.ts.map +1 -0
- package/dist/agents/built-in.js +6 -0
- package/dist/agents/built-in.js.map +1 -0
- package/dist/agents/claude.d.ts +12 -0
- package/dist/agents/claude.d.ts.map +1 -0
- package/dist/agents/claude.js +93 -0
- package/dist/agents/claude.js.map +1 -0
- package/dist/agents/codex.d.ts +6 -0
- package/dist/agents/codex.d.ts.map +1 -0
- package/dist/agents/codex.js +64 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/command-detection.d.ts +6 -0
- package/dist/agents/command-detection.d.ts.map +1 -0
- package/dist/agents/command-detection.js +12 -0
- package/dist/agents/command-detection.js.map +1 -0
- package/dist/agents/gemini.d.ts +6 -0
- package/dist/agents/gemini.d.ts.map +1 -0
- package/dist/agents/gemini.js +36 -0
- package/dist/agents/gemini.js.map +1 -0
- package/dist/cli/agent-commands.d.ts +2 -0
- package/dist/cli/agent-commands.d.ts.map +1 -0
- package/dist/cli/agent-commands.js +87 -0
- package/dist/cli/agent-commands.js.map +1 -0
- package/dist/cli/args.d.ts +9 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +34 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/command-shared.d.ts +53 -0
- package/dist/cli/command-shared.d.ts.map +1 -0
- package/dist/cli/command-shared.js +239 -0
- package/dist/cli/command-shared.js.map +1 -0
- package/dist/cli/commands.d.ts +20 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +20 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/daemon-client.d.ts +30 -0
- package/dist/cli/daemon-client.d.ts.map +1 -0
- package/dist/cli/daemon-client.js +161 -0
- package/dist/cli/daemon-client.js.map +1 -0
- package/dist/cli/daemon-lifecycle.d.ts +47 -0
- package/dist/cli/daemon-lifecycle.d.ts.map +1 -0
- package/dist/cli/daemon-lifecycle.js +262 -0
- package/dist/cli/daemon-lifecycle.js.map +1 -0
- package/dist/cli/daemon-settings.d.ts +9 -0
- package/dist/cli/daemon-settings.d.ts.map +1 -0
- package/dist/cli/daemon-settings.js +168 -0
- package/dist/cli/daemon-settings.js.map +1 -0
- package/dist/cli/directory-commands.d.ts +4 -0
- package/dist/cli/directory-commands.d.ts.map +1 -0
- package/dist/cli/directory-commands.js +190 -0
- package/dist/cli/directory-commands.js.map +1 -0
- package/dist/cli/hook-command.d.ts +14 -0
- package/dist/cli/hook-command.d.ts.map +1 -0
- package/dist/cli/hook-command.js +96 -0
- package/dist/cli/hook-command.js.map +1 -0
- package/dist/cli/install-command.d.ts +2 -0
- package/dist/cli/install-command.d.ts.map +1 -0
- package/dist/cli/install-command.js +91 -0
- package/dist/cli/install-command.js.map +1 -0
- package/dist/cli/lifecycle-commands.d.ts +10 -0
- package/dist/cli/lifecycle-commands.d.ts.map +1 -0
- package/dist/cli/lifecycle-commands.js +524 -0
- package/dist/cli/lifecycle-commands.js.map +1 -0
- package/dist/cli/listen-target.d.ts +13 -0
- package/dist/cli/listen-target.d.ts.map +1 -0
- package/dist/cli/listen-target.js +102 -0
- package/dist/cli/listen-target.js.map +1 -0
- package/dist/cli/orchestration-commands.d.ts +8 -0
- package/dist/cli/orchestration-commands.d.ts.map +1 -0
- package/dist/cli/orchestration-commands.js +340 -0
- package/dist/cli/orchestration-commands.js.map +1 -0
- package/dist/cli/permission-commands.d.ts +2 -0
- package/dist/cli/permission-commands.d.ts.map +1 -0
- package/dist/cli/permission-commands.js +138 -0
- package/dist/cli/permission-commands.js.map +1 -0
- package/dist/cli/runtime-toolchain.d.ts +35 -0
- package/dist/cli/runtime-toolchain.d.ts.map +1 -0
- package/dist/cli/runtime-toolchain.js +184 -0
- package/dist/cli/runtime-toolchain.js.map +1 -0
- package/dist/cli/service-commands.d.ts +19 -0
- package/dist/cli/service-commands.d.ts.map +1 -0
- package/dist/cli/service-commands.js +273 -0
- package/dist/cli/service-commands.js.map +1 -0
- package/dist/cli/session-commands.d.ts +3 -0
- package/dist/cli/session-commands.d.ts.map +1 -0
- package/dist/cli/session-commands.js +146 -0
- package/dist/cli/session-commands.js.map +1 -0
- package/dist/cli/setup-command.d.ts +12 -0
- package/dist/cli/setup-command.d.ts.map +1 -0
- package/dist/cli/setup-command.js +223 -0
- package/dist/cli/setup-command.js.map +1 -0
- package/dist/cli/supervisor-protocol.d.ts +20 -0
- package/dist/cli/supervisor-protocol.d.ts.map +1 -0
- package/dist/cli/supervisor-protocol.js +5 -0
- package/dist/cli/supervisor-protocol.js.map +1 -0
- package/dist/cli/supervisor.d.ts +10 -0
- package/dist/cli/supervisor.d.ts.map +1 -0
- package/dist/cli/supervisor.js +218 -0
- package/dist/cli/supervisor.js.map +1 -0
- package/dist/cli/worktree-commands.d.ts +2 -0
- package/dist/cli/worktree-commands.d.ts.map +1 -0
- package/dist/cli/worktree-commands.js +250 -0
- package/dist/cli/worktree-commands.js.map +1 -0
- package/dist/cli/ws-client.d.ts +20 -0
- package/dist/cli/ws-client.d.ts.map +1 -0
- package/dist/cli/ws-client.js +103 -0
- package/dist/cli/ws-client.js.map +1 -0
- package/dist/core/agent-registry.d.ts +128 -0
- package/dist/core/agent-registry.d.ts.map +1 -0
- package/dist/core/agent-registry.js +131 -0
- package/dist/core/agent-registry.js.map +1 -0
- package/dist/core/config-schema.d.ts +77 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +66 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/config.d.ts +111 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +244 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/daemon.d.ts +113 -0
- package/dist/core/daemon.d.ts.map +1 -0
- package/dist/core/daemon.js +197 -0
- package/dist/core/daemon.js.map +1 -0
- package/dist/core/discovered-sessions.d.ts +7 -0
- package/dist/core/discovered-sessions.d.ts.map +1 -0
- package/dist/core/discovered-sessions.js +39 -0
- package/dist/core/discovered-sessions.js.map +1 -0
- package/dist/core/error-codes.d.ts +31 -0
- package/dist/core/error-codes.d.ts.map +1 -0
- package/dist/core/error-codes.js +30 -0
- package/dist/core/error-codes.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +43 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +183 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +61 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/interfaces.d.ts +115 -0
- package/dist/core/interfaces.d.ts.map +1 -0
- package/dist/core/interfaces.js +9 -0
- package/dist/core/interfaces.js.map +1 -0
- package/dist/core/logger.d.ts +11 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +17 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/metrics.d.ts +24 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +32 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/output.d.ts +13 -0
- package/dist/core/output.d.ts.map +1 -0
- package/dist/core/output.js +22 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/permission-coordinator.d.ts +67 -0
- package/dist/core/permission-coordinator.d.ts.map +1 -0
- package/dist/core/permission-coordinator.js +209 -0
- package/dist/core/permission-coordinator.js.map +1 -0
- package/dist/core/session-manager.d.ts +121 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +354 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/session-state-file.d.ts +20 -0
- package/dist/core/session-state-file.d.ts.map +1 -0
- package/dist/core/session-state-file.js +49 -0
- package/dist/core/session-state-file.js.map +1 -0
- package/dist/core/types.d.ts +250 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +88 -0
- package/dist/core/types.js.map +1 -0
- package/dist/directories/manager.d.ts +32 -0
- package/dist/directories/manager.d.ts.map +1 -0
- package/dist/directories/manager.js +86 -0
- package/dist/directories/manager.js.map +1 -0
- package/dist/discovery/claude.d.ts +29 -0
- package/dist/discovery/claude.d.ts.map +1 -0
- package/dist/discovery/claude.js +55 -0
- package/dist/discovery/claude.js.map +1 -0
- package/dist/discovery/codex.d.ts +11 -0
- package/dist/discovery/codex.d.ts.map +1 -0
- package/dist/discovery/codex.js +365 -0
- package/dist/discovery/codex.js.map +1 -0
- package/dist/discovery/gemini.d.ts +15 -0
- package/dist/discovery/gemini.d.ts.map +1 -0
- package/dist/discovery/gemini.js +151 -0
- package/dist/discovery/gemini.js.map +1 -0
- package/dist/discovery/jsonl-reader.d.ts +122 -0
- package/dist/discovery/jsonl-reader.d.ts.map +1 -0
- package/dist/discovery/jsonl-reader.js +622 -0
- package/dist/discovery/jsonl-reader.js.map +1 -0
- package/dist/discovery/watcher.d.ts +29 -0
- package/dist/discovery/watcher.d.ts.map +1 -0
- package/dist/discovery/watcher.js +383 -0
- package/dist/discovery/watcher.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/installers/base.d.ts +27 -0
- package/dist/hooks/installers/base.d.ts.map +1 -0
- package/dist/hooks/installers/base.js +9 -0
- package/dist/hooks/installers/base.js.map +1 -0
- package/dist/hooks/installers/claude.d.ts +18 -0
- package/dist/hooks/installers/claude.d.ts.map +1 -0
- package/dist/hooks/installers/claude.js +120 -0
- package/dist/hooks/installers/claude.js.map +1 -0
- package/dist/hooks/router.d.ts +63 -0
- package/dist/hooks/router.d.ts.map +1 -0
- package/dist/hooks/router.js +259 -0
- package/dist/hooks/router.js.map +1 -0
- package/dist/hooks/supervision.d.ts +27 -0
- package/dist/hooks/supervision.d.ts.map +1 -0
- package/dist/hooks/supervision.js +67 -0
- package/dist/hooks/supervision.js.map +1 -0
- package/dist/hooks/types.d.ts +171 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +148 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -0
- package/dist/permissions/engine.d.ts +23 -0
- package/dist/permissions/engine.d.ts.map +1 -0
- package/dist/permissions/engine.js +43 -0
- package/dist/permissions/engine.js.map +1 -0
- package/dist/plugins/loader.d.ts +44 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +177 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/server/auth.d.ts +32 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +78 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/discovered-watch-key.d.ts +5 -0
- package/dist/server/discovered-watch-key.d.ts.map +1 -0
- package/dist/server/discovered-watch-key.js +31 -0
- package/dist/server/discovered-watch-key.js.map +1 -0
- package/dist/server/hello-builder.d.ts +17 -0
- package/dist/server/hello-builder.d.ts.map +1 -0
- package/dist/server/hello-builder.js +71 -0
- package/dist/server/hello-builder.js.map +1 -0
- package/dist/server/http-server.d.ts +30 -0
- package/dist/server/http-server.d.ts.map +1 -0
- package/dist/server/http-server.js +561 -0
- package/dist/server/http-server.js.map +1 -0
- package/dist/server/message-normalizers.d.ts +11 -0
- package/dist/server/message-normalizers.d.ts.map +1 -0
- package/dist/server/message-normalizers.js +104 -0
- package/dist/server/message-normalizers.js.map +1 -0
- package/dist/server/pairing-offers.d.ts +78 -0
- package/dist/server/pairing-offers.d.ts.map +1 -0
- package/dist/server/pairing-offers.js +502 -0
- package/dist/server/pairing-offers.js.map +1 -0
- package/dist/server/rate-limiter.d.ts +21 -0
- package/dist/server/rate-limiter.d.ts.map +1 -0
- package/dist/server/rate-limiter.js +61 -0
- package/dist/server/rate-limiter.js.map +1 -0
- package/dist/server/ring-buffer.d.ts +34 -0
- package/dist/server/ring-buffer.d.ts.map +1 -0
- package/dist/server/ring-buffer.js +73 -0
- package/dist/server/ring-buffer.js.map +1 -0
- package/dist/server/security.d.ts +22 -0
- package/dist/server/security.d.ts.map +1 -0
- package/dist/server/security.js +123 -0
- package/dist/server/security.js.map +1 -0
- package/dist/server/ws-command-handlers.d.ts +25 -0
- package/dist/server/ws-command-handlers.d.ts.map +1 -0
- package/dist/server/ws-command-handlers.js +218 -0
- package/dist/server/ws-command-handlers.js.map +1 -0
- package/dist/server/ws-daemon-event-bridge.d.ts +22 -0
- package/dist/server/ws-daemon-event-bridge.d.ts.map +1 -0
- package/dist/server/ws-daemon-event-bridge.js +321 -0
- package/dist/server/ws-daemon-event-bridge.js.map +1 -0
- package/dist/server/ws-limits.d.ts +2 -0
- package/dist/server/ws-limits.d.ts.map +1 -0
- package/dist/server/ws-limits.js +12 -0
- package/dist/server/ws-limits.js.map +1 -0
- package/dist/server/ws-protocol.d.ts +248 -0
- package/dist/server/ws-protocol.d.ts.map +1 -0
- package/dist/server/ws-protocol.js +157 -0
- package/dist/server/ws-protocol.js.map +1 -0
- package/dist/server/ws-server.d.ts +26 -0
- package/dist/server/ws-server.d.ts.map +1 -0
- package/dist/server/ws-server.js +290 -0
- package/dist/server/ws-server.js.map +1 -0
- package/dist/startup-agents.d.ts +6 -0
- package/dist/startup-agents.d.ts.map +1 -0
- package/dist/startup-agents.js +97 -0
- package/dist/startup-agents.js.map +1 -0
- package/dist/startup-prereqs.d.ts +29 -0
- package/dist/startup-prereqs.d.ts.map +1 -0
- package/dist/startup-prereqs.js +209 -0
- package/dist/startup-prereqs.js.map +1 -0
- package/dist/startup-watchers.d.ts +7 -0
- package/dist/startup-watchers.d.ts.map +1 -0
- package/dist/startup-watchers.js +196 -0
- package/dist/startup-watchers.js.map +1 -0
- package/dist/startup.d.ts +20 -0
- package/dist/startup.d.ts.map +1 -0
- package/dist/startup.js +335 -0
- package/dist/startup.js.map +1 -0
- package/dist/tracking/git-tracker.d.ts +52 -0
- package/dist/tracking/git-tracker.d.ts.map +1 -0
- package/dist/tracking/git-tracker.js +277 -0
- package/dist/tracking/git-tracker.js.map +1 -0
- package/dist/tracking/noop-tracker.d.ts +27 -0
- package/dist/tracking/noop-tracker.d.ts.map +1 -0
- package/dist/tracking/noop-tracker.js +42 -0
- package/dist/tracking/noop-tracker.js.map +1 -0
- package/docs/configuration.md +75 -0
- package/docs/developer-workflows.md +107 -0
- package/docs/protocol-matrix.json +155 -0
- package/docs/releasing.md +65 -0
- package/docs/security.md +48 -0
- package/docs/testing.md +112 -0
- package/package.json +84 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { claudeProjectsDir } from './jsonl-reader.js';
|
|
5
|
+
/**
|
|
6
|
+
* Watch ~/.claude/projects/ for changes.
|
|
7
|
+
* Returns a cleanup function to stop watching.
|
|
8
|
+
*/
|
|
9
|
+
export function watchProjects(options) {
|
|
10
|
+
const watchDir = options.watchDir ?? claudeProjectsDir();
|
|
11
|
+
const debounceMs = options.debounceMs ?? 300;
|
|
12
|
+
const recursive = options.recursive ?? false;
|
|
13
|
+
const includeTopLevelFiles = options.includeTopLevelFiles ?? false;
|
|
14
|
+
const subWatchers = new Map();
|
|
15
|
+
const subRetryTimers = new Map();
|
|
16
|
+
const subRetryAttempts = new Map();
|
|
17
|
+
let topWatcher = null;
|
|
18
|
+
let topRetryTimer = null;
|
|
19
|
+
let topRetryAttempt = 0;
|
|
20
|
+
let syncTimer = null;
|
|
21
|
+
let syncInFlight = false;
|
|
22
|
+
let debounceTimer = null;
|
|
23
|
+
let stopped = false;
|
|
24
|
+
const RETRY_MIN_MS = 200;
|
|
25
|
+
const RETRY_MAX_MS = 5_000;
|
|
26
|
+
function backoffMs(attempt) {
|
|
27
|
+
return Math.min(RETRY_MAX_MS, RETRY_MIN_MS * 2 ** Math.max(0, attempt - 1));
|
|
28
|
+
}
|
|
29
|
+
function scheduleChange() {
|
|
30
|
+
if (stopped)
|
|
31
|
+
return;
|
|
32
|
+
if (debounceTimer)
|
|
33
|
+
clearTimeout(debounceTimer);
|
|
34
|
+
debounceTimer = setTimeout(() => {
|
|
35
|
+
if (!stopped) {
|
|
36
|
+
options.onChange();
|
|
37
|
+
}
|
|
38
|
+
}, debounceMs);
|
|
39
|
+
}
|
|
40
|
+
function closeSubWatcher(dirPath) {
|
|
41
|
+
const watcher = subWatchers.get(dirPath);
|
|
42
|
+
if (!watcher)
|
|
43
|
+
return;
|
|
44
|
+
subWatchers.delete(dirPath);
|
|
45
|
+
try {
|
|
46
|
+
watcher.close();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Ignore close errors during cleanup/recovery.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function clearSubRetry(dirPath) {
|
|
53
|
+
const timer = subRetryTimers.get(dirPath);
|
|
54
|
+
if (timer) {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
subRetryTimers.delete(dirPath);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function scheduleSubWatcherRetry(dirPath) {
|
|
60
|
+
if (stopped || subWatchers.has(dirPath) || subRetryTimers.has(dirPath))
|
|
61
|
+
return;
|
|
62
|
+
const attempt = (subRetryAttempts.get(dirPath) ?? 0) + 1;
|
|
63
|
+
subRetryAttempts.set(dirPath, attempt);
|
|
64
|
+
const delay = backoffMs(attempt);
|
|
65
|
+
const timer = setTimeout(() => {
|
|
66
|
+
subRetryTimers.delete(dirPath);
|
|
67
|
+
void setupSubWatcher(dirPath);
|
|
68
|
+
}, delay);
|
|
69
|
+
subRetryTimers.set(dirPath, timer);
|
|
70
|
+
}
|
|
71
|
+
async function setupSubWatcher(dirPath) {
|
|
72
|
+
if (stopped || subWatchers.has(dirPath))
|
|
73
|
+
return;
|
|
74
|
+
try {
|
|
75
|
+
const stat = await fsp.stat(dirPath);
|
|
76
|
+
if (!stat.isDirectory())
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
scheduleSubWatcherRetry(dirPath);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const watcher = fs.watch(dirPath, { persistent: false }, (_event, filename) => {
|
|
85
|
+
if (!filename) {
|
|
86
|
+
scheduleChange();
|
|
87
|
+
scheduleSync();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const fileName = String(filename);
|
|
91
|
+
if (isSessionJsonl(fileName)) {
|
|
92
|
+
const filePath = path.join(dirPath, fileName);
|
|
93
|
+
options.onFileChanged?.(filePath);
|
|
94
|
+
scheduleChange();
|
|
95
|
+
}
|
|
96
|
+
// Handles directory renames/removals and late directory creation.
|
|
97
|
+
scheduleSync();
|
|
98
|
+
});
|
|
99
|
+
watcher.on('error', () => {
|
|
100
|
+
closeSubWatcher(dirPath);
|
|
101
|
+
scheduleSubWatcherRetry(dirPath);
|
|
102
|
+
});
|
|
103
|
+
watcher.on('close', () => {
|
|
104
|
+
if (!stopped && subWatchers.has(dirPath)) {
|
|
105
|
+
subWatchers.delete(dirPath);
|
|
106
|
+
scheduleSubWatcherRetry(dirPath);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
subWatchers.set(dirPath, watcher);
|
|
110
|
+
subRetryAttempts.delete(dirPath);
|
|
111
|
+
clearSubRetry(dirPath);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
scheduleSubWatcherRetry(dirPath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function syncSubWatchers() {
|
|
118
|
+
if (stopped)
|
|
119
|
+
return;
|
|
120
|
+
if (syncInFlight)
|
|
121
|
+
return;
|
|
122
|
+
syncInFlight = true;
|
|
123
|
+
// Watch existing project subdirectories for new/changed JSONL files
|
|
124
|
+
try {
|
|
125
|
+
const entries = await fsp.readdir(watchDir, { withFileTypes: true });
|
|
126
|
+
const nextDirs = new Set();
|
|
127
|
+
if (recursive) {
|
|
128
|
+
await collectNestedDirectories(watchDir, nextDirs);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
for (const entry of entries) {
|
|
132
|
+
if (entry.isDirectory()) {
|
|
133
|
+
nextDirs.add(path.join(watchDir, entry.name));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const dirPath of subWatchers.keys()) {
|
|
138
|
+
if (!nextDirs.has(dirPath)) {
|
|
139
|
+
closeSubWatcher(dirPath);
|
|
140
|
+
clearSubRetry(dirPath);
|
|
141
|
+
subRetryAttempts.delete(dirPath);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
await Promise.all([...nextDirs].map((dirPath) => setupSubWatcher(dirPath)));
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// watchDir may not exist yet or may be temporarily unavailable.
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
syncInFlight = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function scheduleSync(delayMs = 50) {
|
|
154
|
+
if (stopped)
|
|
155
|
+
return;
|
|
156
|
+
if (syncTimer)
|
|
157
|
+
clearTimeout(syncTimer);
|
|
158
|
+
syncTimer = setTimeout(() => {
|
|
159
|
+
syncTimer = null;
|
|
160
|
+
void syncSubWatchers();
|
|
161
|
+
}, delayMs);
|
|
162
|
+
}
|
|
163
|
+
function startTopWatcher() {
|
|
164
|
+
if (stopped || topWatcher)
|
|
165
|
+
return;
|
|
166
|
+
try {
|
|
167
|
+
topWatcher = fs.watch(watchDir, { persistent: false }, (_event, filename) => {
|
|
168
|
+
if (filename) {
|
|
169
|
+
scheduleChange();
|
|
170
|
+
if (includeTopLevelFiles) {
|
|
171
|
+
const fileName = String(filename);
|
|
172
|
+
if (isSessionJsonl(fileName)) {
|
|
173
|
+
options.onFileChanged?.(path.join(watchDir, fileName));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Some platforms emit null filename on directory changes; still resync.
|
|
178
|
+
scheduleSync();
|
|
179
|
+
});
|
|
180
|
+
topWatcher.on('error', () => {
|
|
181
|
+
if (topWatcher) {
|
|
182
|
+
try {
|
|
183
|
+
topWatcher.close();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// Ignore close errors during retry setup.
|
|
187
|
+
}
|
|
188
|
+
topWatcher = null;
|
|
189
|
+
}
|
|
190
|
+
scheduleTopWatcherRetry();
|
|
191
|
+
});
|
|
192
|
+
topWatcher.on('close', () => {
|
|
193
|
+
if (topWatcher)
|
|
194
|
+
topWatcher = null;
|
|
195
|
+
if (!stopped)
|
|
196
|
+
scheduleTopWatcherRetry();
|
|
197
|
+
});
|
|
198
|
+
topRetryAttempt = 0;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
scheduleTopWatcherRetry();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function scheduleTopWatcherRetry() {
|
|
205
|
+
if (stopped || topRetryTimer)
|
|
206
|
+
return;
|
|
207
|
+
topRetryAttempt += 1;
|
|
208
|
+
const delay = backoffMs(topRetryAttempt);
|
|
209
|
+
topRetryTimer = setTimeout(() => {
|
|
210
|
+
topRetryTimer = null;
|
|
211
|
+
startTopWatcher();
|
|
212
|
+
}, delay);
|
|
213
|
+
}
|
|
214
|
+
async function startWatching() {
|
|
215
|
+
try {
|
|
216
|
+
await fsp.access(watchDir);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
scheduleTopWatcherRetry();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
startTopWatcher();
|
|
223
|
+
await syncSubWatchers();
|
|
224
|
+
}
|
|
225
|
+
// Start watching (async, but we don't need to await)
|
|
226
|
+
void startWatching();
|
|
227
|
+
// Return cleanup function
|
|
228
|
+
return () => {
|
|
229
|
+
stopped = true;
|
|
230
|
+
if (syncTimer)
|
|
231
|
+
clearTimeout(syncTimer);
|
|
232
|
+
if (debounceTimer)
|
|
233
|
+
clearTimeout(debounceTimer);
|
|
234
|
+
if (topRetryTimer)
|
|
235
|
+
clearTimeout(topRetryTimer);
|
|
236
|
+
for (const timer of subRetryTimers.values())
|
|
237
|
+
clearTimeout(timer);
|
|
238
|
+
subRetryTimers.clear();
|
|
239
|
+
subRetryAttempts.clear();
|
|
240
|
+
for (const dirPath of subWatchers.keys()) {
|
|
241
|
+
closeSubWatcher(dirPath);
|
|
242
|
+
}
|
|
243
|
+
if (topWatcher) {
|
|
244
|
+
try {
|
|
245
|
+
topWatcher.close();
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// Ignore cleanup errors.
|
|
249
|
+
}
|
|
250
|
+
topWatcher = null;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export function createSessionTailer(filePath) {
|
|
255
|
+
let sessionId = path.basename(filePath, '.jsonl');
|
|
256
|
+
let lastSize = 0;
|
|
257
|
+
let lastInode = null;
|
|
258
|
+
let partialLine = '';
|
|
259
|
+
return {
|
|
260
|
+
get sessionId() {
|
|
261
|
+
return sessionId;
|
|
262
|
+
},
|
|
263
|
+
filePath,
|
|
264
|
+
async readNew() {
|
|
265
|
+
let stat;
|
|
266
|
+
try {
|
|
267
|
+
stat = await fsp.stat(filePath);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
const currentSize = stat.size;
|
|
273
|
+
const currentInode = stat.ino;
|
|
274
|
+
const inodeChanged = lastInode !== null && currentInode !== lastInode;
|
|
275
|
+
// File replaced/rotated or truncated: restart read from beginning.
|
|
276
|
+
if (inodeChanged || currentSize < lastSize) {
|
|
277
|
+
lastSize = 0;
|
|
278
|
+
partialLine = '';
|
|
279
|
+
}
|
|
280
|
+
else if (currentSize === lastSize) {
|
|
281
|
+
lastInode = currentInode;
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
// Read only the new bytes
|
|
285
|
+
const fd = await fsp.open(filePath, 'r');
|
|
286
|
+
try {
|
|
287
|
+
const bytesToRead = currentSize - lastSize;
|
|
288
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
289
|
+
await fd.read(buffer, 0, bytesToRead, lastSize);
|
|
290
|
+
lastSize = currentSize;
|
|
291
|
+
lastInode = currentInode;
|
|
292
|
+
// Parse new lines
|
|
293
|
+
const text = partialLine + buffer.toString('utf-8');
|
|
294
|
+
const rawLines = text.split('\n');
|
|
295
|
+
if (text.endsWith('\n')) {
|
|
296
|
+
partialLine = '';
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
partialLine = rawLines.pop() ?? '';
|
|
300
|
+
}
|
|
301
|
+
const results = [];
|
|
302
|
+
for (const line of rawLines) {
|
|
303
|
+
if (!line.trim())
|
|
304
|
+
continue;
|
|
305
|
+
try {
|
|
306
|
+
const parsed = JSON.parse(line);
|
|
307
|
+
results.push(parsed);
|
|
308
|
+
const detected = detectSessionId(parsed);
|
|
309
|
+
if (detected) {
|
|
310
|
+
sessionId = detected;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// Malformed line — skip
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return results;
|
|
318
|
+
}
|
|
319
|
+
finally {
|
|
320
|
+
await fd.close();
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function isSessionJsonl(fileName) {
|
|
326
|
+
return fileName.endsWith('.jsonl');
|
|
327
|
+
}
|
|
328
|
+
async function collectNestedDirectories(rootDir, out) {
|
|
329
|
+
const queue = [rootDir];
|
|
330
|
+
while (queue.length > 0) {
|
|
331
|
+
const current = queue.shift();
|
|
332
|
+
if (!current)
|
|
333
|
+
continue;
|
|
334
|
+
let entries;
|
|
335
|
+
try {
|
|
336
|
+
entries = await fsp.readdir(current, { withFileTypes: true });
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
for (const entry of entries) {
|
|
342
|
+
if (!entry.isDirectory())
|
|
343
|
+
continue;
|
|
344
|
+
const full = path.join(current, entry.name);
|
|
345
|
+
out.add(full);
|
|
346
|
+
queue.push(full);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function detectSessionId(value) {
|
|
351
|
+
if (typeof value !== 'object' || value === null)
|
|
352
|
+
return null;
|
|
353
|
+
const rec = value;
|
|
354
|
+
const direct = [
|
|
355
|
+
rec['sessionId'],
|
|
356
|
+
rec['session_id'],
|
|
357
|
+
rec['threadId'],
|
|
358
|
+
rec['thread_id'],
|
|
359
|
+
rec['id'],
|
|
360
|
+
];
|
|
361
|
+
for (const candidate of direct) {
|
|
362
|
+
if (typeof candidate === 'string' && candidate)
|
|
363
|
+
return candidate;
|
|
364
|
+
}
|
|
365
|
+
const payload = typeof rec['payload'] === 'object' && rec['payload'] !== null
|
|
366
|
+
? rec['payload']
|
|
367
|
+
: null;
|
|
368
|
+
if (!payload)
|
|
369
|
+
return null;
|
|
370
|
+
const nested = [
|
|
371
|
+
payload['sessionId'],
|
|
372
|
+
payload['session_id'],
|
|
373
|
+
payload['threadId'],
|
|
374
|
+
payload['thread_id'],
|
|
375
|
+
payload['id'],
|
|
376
|
+
];
|
|
377
|
+
for (const candidate of nested) {
|
|
378
|
+
if (typeof candidate === 'string' && candidate)
|
|
379
|
+
return candidate;
|
|
380
|
+
}
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/discovery/watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks module — barrel export.
|
|
3
|
+
*/
|
|
4
|
+
export { HookRouter } from './router.js';
|
|
5
|
+
export { SupervisionManager } from './supervision.js';
|
|
6
|
+
export { ClaudeHookInstaller } from './installers/claude.js';
|
|
7
|
+
export type { HookInstaller, HookInstallerConfig } from './installers/base.js';
|
|
8
|
+
export type { HookEventKind, HookEventDefinition, HookResponse, HookBaseInput } from './types.js';
|
|
9
|
+
export { HOOK_EVENT_KINDS, DEFAULT_EVENT_DEFINITIONS, HOOK_INPUT_SCHEMAS } from './types.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks module — barrel export.
|
|
3
|
+
*/
|
|
4
|
+
export { HookRouter } from './router.js';
|
|
5
|
+
export { SupervisionManager } from './supervision.js';
|
|
6
|
+
export { ClaudeHookInstaller } from './installers/claude.js';
|
|
7
|
+
export { HOOK_EVENT_KINDS, DEFAULT_EVENT_DEFINITIONS, HOOK_INPUT_SCHEMAS } from './types.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HookInstaller interface — adapter-agnostic contract for installing hooks.
|
|
3
|
+
*
|
|
4
|
+
* Each agent adapter (Claude Code, Gemini, Cursor, etc.) has its own config
|
|
5
|
+
* format and location. Installers abstract that away so `vpd install` can
|
|
6
|
+
* install hooks for all detected agents uniformly.
|
|
7
|
+
*/
|
|
8
|
+
import type { HookEventKind } from '../types.js';
|
|
9
|
+
export interface HookInstallerConfig {
|
|
10
|
+
/** The vpd binary path to use in hook commands. */
|
|
11
|
+
vpdBinaryPath: string;
|
|
12
|
+
/** The daemon port for hook HTTP calls. */
|
|
13
|
+
daemonPort: number;
|
|
14
|
+
/** Which hook events to install. */
|
|
15
|
+
events: HookEventKind[];
|
|
16
|
+
}
|
|
17
|
+
export interface HookInstaller {
|
|
18
|
+
/** Human-readable adapter name (e.g., 'Claude Code', 'Gemini CLI'). */
|
|
19
|
+
readonly adapterName: string;
|
|
20
|
+
/** Install hooks into the agent's configuration. Returns true if changed. */
|
|
21
|
+
install(config: HookInstallerConfig): Promise<boolean>;
|
|
22
|
+
/** Remove all Viewport hooks from the agent's configuration. Returns true if changed. */
|
|
23
|
+
uninstall(): Promise<boolean>;
|
|
24
|
+
/** Check if Viewport hooks are currently installed. */
|
|
25
|
+
isInstalled(): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/hooks/installers/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvD,yFAAyF;IACzF,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9B,uDAAuD;IACvD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HookInstaller interface — adapter-agnostic contract for installing hooks.
|
|
3
|
+
*
|
|
4
|
+
* Each agent adapter (Claude Code, Gemini, Cursor, etc.) has its own config
|
|
5
|
+
* format and location. Installers abstract that away so `vpd install` can
|
|
6
|
+
* install hooks for all detected agents uniformly.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/hooks/installers/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hook installer — merges Viewport hooks into ~/.claude/settings.json.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code reads hooks from the global settings file on session start.
|
|
5
|
+
* This installer adds/updates Viewport hook entries without disturbing
|
|
6
|
+
* any user-configured hooks.
|
|
7
|
+
*
|
|
8
|
+
* Hook entries are tagged with a marker comment in the command so we can
|
|
9
|
+
* identify and update them on reinstall or remove them on uninstall.
|
|
10
|
+
*/
|
|
11
|
+
import type { HookInstaller, HookInstallerConfig } from './base.js';
|
|
12
|
+
export declare class ClaudeHookInstaller implements HookInstaller {
|
|
13
|
+
readonly adapterName = "Claude Code";
|
|
14
|
+
install(config: HookInstallerConfig): Promise<boolean>;
|
|
15
|
+
uninstall(): Promise<boolean>;
|
|
16
|
+
isInstalled(): Promise<boolean>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/hooks/installers/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAwBpE,qBAAa,mBAAoB,YAAW,aAAa;IACvD,QAAQ,CAAC,WAAW,iBAAiB;IAE/B,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IA6CtD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IA0C7B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAoBtC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hook installer — merges Viewport hooks into ~/.claude/settings.json.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code reads hooks from the global settings file on session start.
|
|
5
|
+
* This installer adds/updates Viewport hook entries without disturbing
|
|
6
|
+
* any user-configured hooks.
|
|
7
|
+
*
|
|
8
|
+
* Hook entries are tagged with a marker comment in the command so we can
|
|
9
|
+
* identify and update them on reinstall or remove them on uninstall.
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs/promises';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
const VIEWPORT_MARKER = '--viewport-hook';
|
|
15
|
+
function settingsPath() {
|
|
16
|
+
return path.join(os.homedir(), '.claude', 'settings.json');
|
|
17
|
+
}
|
|
18
|
+
/** Build the hook command string for a given event. */
|
|
19
|
+
function buildCommand(vpdPath, port, event) {
|
|
20
|
+
// vpdPath may be multi-word in dev mode (e.g. "npx tsx /path/to/index.ts")
|
|
21
|
+
// Only quote single-word paths that might contain spaces
|
|
22
|
+
const cmd = vpdPath.includes(' ') ? vpdPath : `"${vpdPath}"`;
|
|
23
|
+
return `${cmd} hook notify --event ${event} --port ${port} ${VIEWPORT_MARKER}`;
|
|
24
|
+
}
|
|
25
|
+
/** Determine the timeout for a hook event. */
|
|
26
|
+
function timeoutForEvent(event) {
|
|
27
|
+
// PermissionRequest blocks waiting for supervisor response — long timeout
|
|
28
|
+
if (event === 'PermissionRequest')
|
|
29
|
+
return 120;
|
|
30
|
+
return 5;
|
|
31
|
+
}
|
|
32
|
+
export class ClaudeHookInstaller {
|
|
33
|
+
adapterName = 'Claude Code';
|
|
34
|
+
async install(config) {
|
|
35
|
+
const filePath = settingsPath();
|
|
36
|
+
const settings = await readSettings(filePath);
|
|
37
|
+
const hooks = (settings.hooks ?? {});
|
|
38
|
+
settings.hooks = hooks;
|
|
39
|
+
let changed = false;
|
|
40
|
+
for (const event of config.events) {
|
|
41
|
+
const hookEntry = {
|
|
42
|
+
type: 'command',
|
|
43
|
+
command: buildCommand(config.vpdBinaryPath, config.daemonPort, event),
|
|
44
|
+
timeout: timeoutForEvent(event),
|
|
45
|
+
};
|
|
46
|
+
const existing = hooks[event] ?? [];
|
|
47
|
+
// Remove any existing Viewport entries
|
|
48
|
+
const filtered = existing.filter((entry) => !entry.hooks?.some((h) => typeof h.command === 'string' && h.command.includes(VIEWPORT_MARKER)));
|
|
49
|
+
// Add our entry
|
|
50
|
+
filtered.push({ hooks: [hookEntry] });
|
|
51
|
+
if (JSON.stringify(filtered) !== JSON.stringify(existing)) {
|
|
52
|
+
hooks[event] = filtered;
|
|
53
|
+
changed = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (changed) {
|
|
57
|
+
await writeSettings(filePath, settings);
|
|
58
|
+
}
|
|
59
|
+
return changed;
|
|
60
|
+
}
|
|
61
|
+
async uninstall() {
|
|
62
|
+
const filePath = settingsPath();
|
|
63
|
+
let settings;
|
|
64
|
+
try {
|
|
65
|
+
settings = await readSettings(filePath);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false; // No settings file — nothing to uninstall
|
|
69
|
+
}
|
|
70
|
+
const hooks = settings.hooks;
|
|
71
|
+
if (!hooks)
|
|
72
|
+
return false;
|
|
73
|
+
let changed = false;
|
|
74
|
+
for (const [event, entries] of Object.entries(hooks)) {
|
|
75
|
+
const filtered = entries.filter((entry) => !entry.hooks?.some((h) => typeof h.command === 'string' && h.command.includes(VIEWPORT_MARKER)));
|
|
76
|
+
if (filtered.length !== entries.length) {
|
|
77
|
+
if (filtered.length === 0) {
|
|
78
|
+
delete hooks[event];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
hooks[event] = filtered;
|
|
82
|
+
}
|
|
83
|
+
changed = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (changed) {
|
|
87
|
+
await writeSettings(filePath, settings);
|
|
88
|
+
}
|
|
89
|
+
return changed;
|
|
90
|
+
}
|
|
91
|
+
async isInstalled() {
|
|
92
|
+
try {
|
|
93
|
+
const settings = await readSettings(settingsPath());
|
|
94
|
+
const hooks = settings.hooks;
|
|
95
|
+
if (!hooks)
|
|
96
|
+
return false;
|
|
97
|
+
return Object.values(hooks).some((entries) => entries.some((entry) => entry.hooks?.some((h) => typeof h.command === 'string' && h.command.includes(VIEWPORT_MARKER))));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Settings file I/O
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
async function readSettings(filePath) {
|
|
108
|
+
try {
|
|
109
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
110
|
+
return JSON.parse(content);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function writeSettings(filePath, settings) {
|
|
117
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
118
|
+
await fs.writeFile(filePath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/hooks/installers/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAIzB,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAC7D,CAAC;AAED,uDAAuD;AACvD,SAAS,YAAY,CAAC,OAAe,EAAE,IAAY,EAAE,KAAoB;IACvE,2EAA2E;IAC3E,yDAAyD;IACzD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC;IAC7D,OAAO,GAAG,GAAG,wBAAwB,KAAK,WAAW,IAAI,IAAI,eAAe,EAAE,CAAC;AACjF,CAAC;AAED,8CAA8C;AAC9C,SAAS,eAAe,CAAC,KAAoB;IAC3C,0EAA0E;IAC1E,IAAI,KAAK,KAAK,mBAAmB;QAAE,OAAO,GAAG,CAAC;IAC9C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,OAAO,mBAAmB;IACrB,WAAW,GAAG,aAAa,CAAC;IAErC,KAAK,CAAC,OAAO,CAAC,MAA2B;QACvC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE9C,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAGlC,CAAC;QACF,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;QAEvB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG;gBAChB,IAAI,EAAE,SAAkB;gBACxB,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC;gBACrE,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC;aAChC,CAAC;YAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAEpC,uCAAuC;YACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAC9B,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAChB,CAAC,CAA0B,EAAE,EAAE,CAC7B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CACvE,CACJ,CAAC;YAEF,gBAAgB;YAChB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAEtC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1D,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;gBACxB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAEhC,IAAI,QAAiC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC,CAAC,0CAA0C;QAC1D,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAGtB,CAAC;QACF,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAC7B,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAChB,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAC5E,CACJ,CAAC;YAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;gBACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;gBAC1B,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAGtB,CAAC;YACF,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YAEzB,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACrB,KAAK,CAAC,KAAK,EAAE,IAAI,CACf,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAC5E,CACF,CACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,QAAiC;IAC9E,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAClF,CAAC"}
|