apt-mcp-agent-setup 3.5.36 → 3.5.61

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 (183) hide show
  1. package/README.md +123 -123
  2. package/bin/cli.js +1 -1
  3. package/build-input.json +302 -241
  4. package/bundle/NOTICES.md +0 -0
  5. package/bundle/core.enc +0 -0
  6. package/bundle/mcp-rules.enc +0 -0
  7. package/bundle/skills-aso.enc +0 -0
  8. package/bundle/skills-ba.enc +0 -0
  9. package/bundle/skills-base.enc +0 -0
  10. package/bundle/skills-be.enc +0 -0
  11. package/bundle/skills-design.enc +0 -0
  12. package/bundle/skills-fe.enc +0 -0
  13. package/bundle/skills-marketing.enc +0 -0
  14. package/bundle/skills-mobile.enc +0 -0
  15. package/bundle/skills-pm.enc +0 -0
  16. package/docs/technical-sources.md +7 -7
  17. package/integrity-manifest.json +183 -178
  18. package/package.json +1 -1
  19. package/release-check.js +30 -30
  20. package/src/backends/browser-tools.js +1 -1
  21. package/src/backends/index-cache-authority.js +1 -1
  22. package/src/backends/index-command.js +1 -1
  23. package/src/backends/index-contract.json +11 -11
  24. package/src/backends/index-maintenance.js +1 -1
  25. package/src/backends/index-store.js +1 -1
  26. package/src/backends/linked-worktrees.js +1 -0
  27. package/src/backends/profiles.js +1 -1
  28. package/src/backends/review_graph.py +125 -103
  29. package/src/backends/source-discovery.js +1 -1
  30. package/src/core/admission-fence.js +1 -1
  31. package/src/core/aso-import.js +1 -1
  32. package/src/core/backend-lease-recovery.js +1 -1
  33. package/src/core/boot-evidence.js +1 -1
  34. package/src/core/caller-context.js +1 -1
  35. package/src/core/catalog.js +1 -1
  36. package/src/core/claude-caller-authority.js +1 -1
  37. package/src/core/claude-invocation.js +1 -1
  38. package/src/core/claude-launch-recovery.js +1 -1
  39. package/src/core/claude-native.js +1 -1
  40. package/src/core/claude-plan.js +1 -1
  41. package/src/core/claude-transcript-scan.js +1 -1
  42. package/src/core/claude-worker-transcript.js +1 -1
  43. package/src/core/codex-host-metadata.js +1 -1
  44. package/src/core/codex-transcript-receipt.js +1 -1
  45. package/src/core/connection-inspector.js +1 -1
  46. package/src/core/content-hash-cache.js +1 -1
  47. package/src/core/context-metrics.js +1 -1
  48. package/src/core/doctor.js +1 -1
  49. package/src/core/draining-completion.js +1 -1
  50. package/src/core/execution.js +1 -1
  51. package/src/core/git-context.js +1 -1
  52. package/src/core/hook-bridge.js +1 -1
  53. package/src/core/hook-diagnostics.js +1 -1
  54. package/src/core/hook-lease.js +1 -1
  55. package/src/core/host-adapters.js +1 -1
  56. package/src/core/interrupted-boot-transport-proof.js +1 -1
  57. package/src/core/interrupted-natural-closure-proof.js +1 -1
  58. package/src/core/interrupted-operation-audit.js +1 -1
  59. package/src/core/interrupted-transport-proof.js +1 -1
  60. package/src/core/ipc-envelope.js +1 -1
  61. package/src/core/legacy-retirement-proof.js +1 -1
  62. package/src/core/memory-scope.js +1 -1
  63. package/src/core/memory-store.js +1 -1
  64. package/src/core/model-inventory.js +1 -1
  65. package/src/core/model-routing.js +1 -1
  66. package/src/core/native-dispatch.js +1 -1
  67. package/src/core/native-receipt.js +1 -1
  68. package/src/core/native-retirement.js +1 -1
  69. package/src/core/node-version.js +1 -1
  70. package/src/core/npm-cli.js +1 -1
  71. package/src/core/owned-command-child.js +1 -1
  72. package/src/core/owned-command.js +1 -1
  73. package/src/core/owned-lock.js +1 -1
  74. package/src/core/owned-process.js +1 -1
  75. package/src/core/pipeline-journal.js +1 -1
  76. package/src/core/presentations.js +1 -1
  77. package/src/core/quality-artifacts.js +1 -1
  78. package/src/core/quality.js +1 -1
  79. package/src/core/read-command.js +1 -1
  80. package/src/core/readonly-skill.js +1 -1
  81. package/src/core/recovery-archive.js +1 -1
  82. package/src/core/recovery-proof.js +1 -1
  83. package/src/core/resource-transaction.js +1 -1
  84. package/src/core/run-checkpoint.js +1 -1
  85. package/src/core/run-compatibility.js +1 -1
  86. package/src/core/run-owner.js +1 -0
  87. package/src/core/run-state-codec.js +1 -1
  88. package/src/core/runtime-authority.js +1 -1
  89. package/src/core/runtime-info.js +1 -1
  90. package/src/core/runtime-ownership.js +1 -1
  91. package/src/core/session.js +1 -1
  92. package/src/core/shared-checkout.js +1 -1
  93. package/src/core/skill-companions.js +1 -1
  94. package/src/core/skill-names.js +1 -1
  95. package/src/core/storage-retry.js +1 -1
  96. package/src/core/tool-contracts.js +1 -1
  97. package/src/core/transport-boot-contract.json +12 -12
  98. package/src/core/transport-close-contract.json +10 -10
  99. package/src/core/transport-contract.json +10 -10
  100. package/src/core/transport-pending-boot-contract.json +12 -12
  101. package/src/core/update-control.js +1 -1
  102. package/src/core/upgrade-runs.js +1 -1
  103. package/src/core/upgrade-stop.js +1 -1
  104. package/src/core/windows-job.js +1 -1
  105. package/src/core/workflow-policy.js +1 -1
  106. package/src/core/workspace-generation.js +1 -1
  107. package/src/core/workspace-path.js +1 -1
  108. package/src/installer/bounded-command.js +1 -1
  109. package/src/installer/candidate-preflight.js +1 -1
  110. package/src/installer/claude-commands.js +1 -1
  111. package/src/installer/codex-hook-trust.js +1 -0
  112. package/src/installer/connection-activation.js +1 -1
  113. package/src/installer/connection-supervisor.js +1 -1
  114. package/src/installer/deployment-draft.js +1 -1
  115. package/src/installer/gateway-context.js +1 -1
  116. package/src/installer/gateway-migration.js +1 -1
  117. package/src/installer/gateway-runtime.js +1 -1
  118. package/src/installer/global-setup.js +1 -1
  119. package/src/installer/hook-context-client.js +1 -1
  120. package/src/installer/hook-dispatcher.js +179 -179
  121. package/src/installer/host-hooks.js +1 -1
  122. package/src/installer/index-interruption-recovery.js +1 -1
  123. package/src/installer/index-recovery.js +1 -1
  124. package/src/installer/install-intent.js +1 -1
  125. package/src/installer/interrupted-operation-recovery.js +1 -1
  126. package/src/installer/legacy-prepared-plan.js +1 -1
  127. package/src/installer/legacy-registration.js +1 -1
  128. package/src/installer/managed-config.js +1 -1
  129. package/src/installer/migration-scope.js +1 -1
  130. package/src/installer/platform-config.js +1 -1
  131. package/src/installer/prerequisites.js +1 -1
  132. package/src/installer/presentations.js +1 -1
  133. package/src/installer/project-outcome.js +1 -1
  134. package/src/installer/project-setup.js +1 -1
  135. package/src/installer/recovery-backup-retention.js +1 -1
  136. package/src/installer/registration-closure.js +1 -1
  137. package/src/installer/registration-plan.js +1 -1
  138. package/src/installer/registration-receipt.js +1 -1
  139. package/src/installer/registrations.js +1 -1
  140. package/src/installer/runtime-activation.js +1 -1
  141. package/src/installer/runtime-child.js +1 -1
  142. package/src/installer/runtime-cleanup.js +1 -1
  143. package/src/installer/runtime-lock.js +1 -1
  144. package/src/installer/runtime-store.js +1 -1
  145. package/src/installer/runtime-supervisor.js +1 -1
  146. package/src/installer/setup-wizard.js +1 -1
  147. package/src/installer/stale-run-release.js +1 -1
  148. package/src/installer/uninstall.js +1 -0
  149. package/src/installer/update-addons.js +1 -1
  150. package/src/installer/update-cleanup.js +1 -1
  151. package/src/installer/update-executor.js +1 -1
  152. package/src/installer/update-history.js +1 -1
  153. package/src/installer/update-registration.js +1 -1
  154. package/src/installer/update-report.js +1 -1
  155. package/src/installer/update-request.js +1 -1
  156. package/src/installer/update-scope.js +1 -1
  157. package/src/installer/workspace-registry.js +1 -1
  158. package/src/installer/workspace-transaction.js +1 -1
  159. package/src/installer/workspace-update.js +1 -1
  160. package/src/license/crypto.js +1 -1
  161. package/src/license/fingerprint.js +1 -1
  162. package/src/license/terms.js +1 -1
  163. package/src/license/verify.js +1 -1
  164. package/src/presets/index.js +1 -1
  165. package/src/proxy/backends.js +1 -1
  166. package/src/proxy/browser-sessions.js +1 -1
  167. package/src/proxy/core-tools.js +1 -1
  168. package/src/proxy/pipeline.js +1 -1
  169. package/src/proxy/public-catalog.js +1 -1
  170. package/src/proxy/router.config.js +1 -1
  171. package/src/proxy/router.js +1 -1
  172. package/src/proxy/run-summary.js +1 -1
  173. package/src/proxy/server-instructions.js +1 -0
  174. package/src/proxy/server.js +1 -1
  175. package/src/proxy/workspace-gateway.js +1 -1
  176. package/src/templates/AGENTS.md +1 -1
  177. package/src/templates/CLAUDE.md +1 -1
  178. package/src/templates/GEMINI.md +1 -1
  179. package/src/templates/apt-runtime.md +5 -4
  180. package/src/templates/copilot-instructions.md +1 -1
  181. package/src/templates/cursorrules.mdc +1 -1
  182. package/src/templates/mcp-tools.md +4 -4
  183. package/src/templates/windsurfrules.md +1 -1
@@ -1,179 +1,179 @@
1
- 'use strict';
2
-
3
- // Embedded with a trusted installation key. Only built-in modules may be used
4
- // until the committed release has been verified.
5
- function hookDispatcher(root, publicKey) {
6
- return { runCLI(host, event, projectPath, executionOptions = {}) {
7
- const fs = require('node:fs'), path = require('node:path'), crypto = require('node:crypto');
8
- // Host adapters pass the workspace as base64 so hook command shells never
9
- // reinterpret path data. Keep absolute raw paths usable for internal calls.
10
- const inputPath = String(projectPath);
11
- const decodedProjectPath = Buffer.from(inputPath, 'base64').toString('utf8');
12
- const workspaceInput = path.isAbsolute(inputPath) || !fs.existsSync(decodedProjectPath) ? inputPath : decodedProjectPath;
13
- const workspace = fs.realpathSync(workspaceInput);
14
- const canonical = process.platform === 'win32' ? workspace.toLowerCase() : workspace;
15
- const authorityFile = path.join(workspace, '.agents', 'runtime', 'generation.json');
16
- let selected;
17
- try { selected = JSON.parse(fs.readFileSync(authorityFile, 'utf8')); }
18
- catch (error) {
19
- if (error.code !== 'ENOENT') throw error;
20
- // Migration only: the workspace pin is explicit, never the machine's
21
- // latest pointer or a release inferred from deployed resource version.
22
- selected = JSON.parse(fs.readFileSync(path.join(root, 'workspaces',
23
- crypto.createHash('sha256').update(canonical).digest('hex') + '.json'), 'utf8'));
24
- }
25
- if (selected.workspace && (process.platform === 'win32' ? selected.workspace.toLowerCase() : selected.workspace) !== canonical)
26
- throw Error('HOOK_WORKSPACE_BINDING_CONFLICT');
27
- if (!/^\d+\.\d+\.\d+$/.test(selected.version) || !/^[a-f0-9]{64}$/.test(selected.digest))
28
- throw Error('HOOK_RUNTIME_BINDING_REQUIRED');
29
- const release = path.join(root, 'releases', `${selected.version}-${selected.digest}`);
30
- if (fs.lstatSync(release).isSymbolicLink()) throw Error('HOOK_RUNTIME_LINK_REJECTED');
31
- const manifest = JSON.parse(fs.readFileSync(path.join(release, 'integrity-manifest.json'), 'utf8'));
32
- if (crypto.createHash('sha256').update(JSON.stringify(manifest)).digest('hex') !== selected.digest ||
33
- !crypto.verify(null, Buffer.from(JSON.stringify(manifest.files)), publicKey, Buffer.from(manifest.signature, 'base64url')))
34
- throw Error('HOOK_RUNTIME_SIGNATURE_INVALID');
35
- for (const required of ['src/core/hook-bridge.js'])
36
- if (!manifest.files[required]) throw Error('HOOK_RUNTIME_RECONNECT_REQUIRED');
37
- for (const [file, digest] of Object.entries(manifest.files)) {
38
- if (path.isAbsolute(file) || file.includes('\\') || file.split('/').some(part => !part || part === '..' || part === '.'))
39
- throw Error('HOOK_RUNTIME_PATH_INVALID');
40
- let cursor = release;
41
- for (const part of file.split('/')) {
42
- cursor = path.join(cursor, part);
43
- if (fs.lstatSync(cursor).isSymbolicLink()) throw Error('HOOK_RUNTIME_LINK_REJECTED');
44
- }
45
- if (crypto.createHash('sha256').update(fs.readFileSync(cursor)).digest('hex') !== digest)
46
- throw Error('HOOK_RUNTIME_INTEGRITY_INVALID');
47
- }
48
- return require(path.join(release, 'src/core/hook-bridge.js')).runCLI(host, event,
49
- Buffer.from(workspace, 'utf8').toString('base64'), executionOptions);
50
- } };
51
- }
52
-
53
- // The parent only uses built-ins. Synchronous hashing/locks in the signed
54
- // worker cannot prevent the parent from producing a blocking decision.
55
- function superviseHook(root, publicKey, dispatcherSource, args, timeoutMs, passive) {
56
- const cp = require('node:child_process'), crypto = require('node:crypto');
57
- const lease = { id: crypto.randomUUID(), notAfter: Date.now() + timeoutMs, maxDurationMs: timeoutMs };
58
- // The worker lives for one host event. APT_HOOK_PROCESS lets its runtime
59
- // locks record a start hint instead of starting PowerShell on every tool call.
60
- const program = `process.env.APT_HOOK_PROCESS = '1';
61
- const dispatcher = (${dispatcherSource})(${JSON.stringify(root)}, ${JSON.stringify(publicKey)});
62
- process.once('message', async message => {
63
- try { await dispatcher.runCLI(...message.args, { hookLease: message.lease }); }
64
- catch (error) { process.stderr.write('APT hook: ' + (error.message || String(error)) + '\\n'); process.exitCode = 2; }
65
- finally { if (process.connected) process.disconnect(); }
66
- });`;
67
- return new Promise((resolve, reject) => {
68
- let settled = false, output = '', errors = '', inputBytes = 0;
69
- const received = [];
70
- // APT allows a passive host read in every session state. A fault of APT
71
- // itself, a missed deadline above all, must not refuse one. The answer is
72
- // the output that lets the call proceed, or null for every other call.
73
- const allowance = () => {
74
- try {
75
- const table = passive && passive[args[0]];
76
- const allow = table && table.events[args[1]];
77
- if (typeof allow !== 'string') return null;
78
- const input = JSON.parse(Buffer.concat(received).toString('utf8'));
79
- const name = input.tool_name;
80
- if (typeof name !== 'string' || input.toolCall !== undefined || input.userStopped === true) return null;
81
- return table.exact.includes(name) || table.insensitive.includes(name.toLowerCase()) ? allow : null;
82
- } catch { return null; }
83
- };
84
- const child = cp.spawn(process.execPath, ['-e', program], { windowsHide: true, stdio: ['pipe', 'pipe', 'pipe', 'ipc'] });
85
- const detach = () => {
86
- clearTimeout(timer); process.stdin.unpipe(child.stdin); process.stdin.removeListener('data', countInput);
87
- child.stdin.destroy();
88
- };
89
- const fail = code => {
90
- if (settled) return;
91
- settled = true; detach();
92
- if (child.connected) child.disconnect();
93
- child.kill(); child.stdout.destroy(); child.stderr.destroy(); child.unref();
94
- const allow = allowance();
95
- if (allow === null) return reject(new Error(code));
96
- process.stderr.write('APT hook: ' + code + ' (not refused)\n');
97
- process.stdout.write(allow + '\n');
98
- process.exitCode = 0;
99
- resolve();
100
- };
101
- const countInput = chunk => {
102
- inputBytes += chunk.length;
103
- if (inputBytes > 2 * 1024 * 1024) fail('HOOK_INPUT_LIMIT'); else received.push(Buffer.from(chunk));
104
- };
105
- const timer = setTimeout(() => fail('HOOK_DEADLINE_EXCEEDED'), timeoutMs);
106
- child.on('error', () => fail('HOOK_WORKER_UNAVAILABLE'));
107
- child.stdin.on('error', () => {});
108
- child.stdout.on('data', chunk => { output += chunk.toString(); if (Buffer.byteLength(output) > 2 * 1024 * 1024) fail('HOOK_OUTPUT_LIMIT'); });
109
- child.stderr.on('data', chunk => { errors += chunk.toString(); if (Buffer.byteLength(errors) > 64 * 1024) fail('HOOK_OUTPUT_LIMIT'); });
110
- child.on('close', code => {
111
- if (settled) return;
112
- if (Date.now() >= lease.notAfter) return fail('HOOK_DEADLINE_EXCEEDED');
113
- settled = true; detach();
114
- // A worker that failed before the bridge could decide refuses nothing
115
- // that APT always allows.
116
- const allow = code === 0 ? null : allowance();
117
- if (code === 0) { if (output) process.stdout.write(output); }
118
- if (errors) process.stderr.write(errors);
119
- if (allow !== null) process.stdout.write(allow + '\n');
120
- process.exitCode = code === 0 || allow !== null ? 0 : 2;
121
- resolve();
122
- });
123
- process.stdin.on('data', countInput); process.stdin.pipe(child.stdin);
124
- child.send({ args, lease }, error => { if (error) fail('HOOK_WORKER_UNAVAILABLE'); });
125
- });
126
- }
127
-
128
- // Only a pre-tool decision may block its host. Any other event observes
129
- // something that already happened, so a dispatcher or runtime fault there is a
130
- // non-blocking error: it must not reject a prompt or force a continuation.
131
- function blockingEvents() {
132
- const { HOSTS } = require('../core/host-adapters');
133
- return Object.fromEntries(Object.entries(HOSTS).map(([host, adapter]) =>
134
- [host, Object.keys(adapter.events).filter(event => adapter.events[event] === 'before-tool')]));
135
- }
136
-
137
- // For each host: the events that guard a tool call, each with the output
138
- // that lets the call proceed, and the tools APT allows in every session state.
139
- function passiveReads() {
140
- const { HOSTS, formatHookResult } = require('../core/host-adapters');
141
- const { passiveHostTools } = require('../core/hook-bridge');
142
- return Object.fromEntries(Object.entries(HOSTS).map(([host, adapter]) => [host, {
143
- events: Object.fromEntries(Object.keys(adapter.events).filter(event => adapter.events[event] === 'before-tool')
144
- .map(event => [event, JSON.stringify(formatHookResult(host, event, { allow: true }).output)])),
145
- ...passiveHostTools(host) }]));
146
- }
147
-
148
- function renderDispatcher(runtimeRoot, publicKey, options = {}) {
149
- const timeoutMs = options.timeoutMs === undefined ? 10000 : options.timeoutMs;
150
- if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 10000) throw new Error('HOOK_DEADLINE_INVALID');
151
- return `'use strict';
152
- const dispatcher = (${hookDispatcher.toString()})(${JSON.stringify(runtimeRoot)}, ${JSON.stringify(publicKey.toString())});
153
- const blockingEvents = ${JSON.stringify(blockingEvents())};
154
- // An unknown host or event stays blocking.
155
- const failureCode = args => !blockingEvents[args[0]] || blockingEvents[args[0]].includes(args[1]) ? 2 : 1;
156
- function reportFailure(error, args) {
157
- process.stderr.write('APT hook: ' + (error && error.message ? error.message : String(error)) + '\\n');
158
- process.exitCode = failureCode(args);
159
- }
160
- module.exports = { runCLI(...args) {
161
- try {
162
- // Generated host commands use node --eval. Direct verifier consumers keep
163
- // the synchronous interface; host execution always has an outer watchdog.
164
- const hostCLI = process.argv.length === 1 && process.execArgv.some(arg => arg === '-e' || arg === '--eval');
165
- const result = hostCLI
166
- ? (${superviseHook.toString()})(${JSON.stringify(runtimeRoot)}, ${JSON.stringify(publicKey.toString())}, ${JSON.stringify(hookDispatcher.toString())}, args, ${timeoutMs}, ${JSON.stringify(passiveReads())})
167
- : dispatcher.runCLI(...args);
168
- if (result && typeof result.then === 'function')
169
- result.then(() => { if (hostCLI && process.exitCode) process.exitCode = failureCode(args); },
170
- error => reportFailure(error, args));
171
- return result;
172
- } catch (error) {
173
- reportFailure(error, args);
174
- }
175
- } };
176
- `;
177
- }
178
-
179
- module.exports = { hookDispatcher, renderDispatcher };
1
+ 'use strict';
2
+
3
+ // Embedded with a trusted installation key. Only built-in modules may be used
4
+ // until the committed release has been verified.
5
+ function hookDispatcher(root, publicKey) {
6
+ return { runCLI(host, event, projectPath, executionOptions = {}) {
7
+ const fs = require('node:fs'), path = require('node:path'), crypto = require('node:crypto');
8
+ // Host adapters pass the workspace as base64 so hook command shells never
9
+ // reinterpret path data. Keep absolute raw paths usable for internal calls.
10
+ const inputPath = String(projectPath);
11
+ const decodedProjectPath = Buffer.from(inputPath, 'base64').toString('utf8');
12
+ const workspaceInput = path.isAbsolute(inputPath) || !fs.existsSync(decodedProjectPath) ? inputPath : decodedProjectPath;
13
+ const workspace = fs.realpathSync(workspaceInput);
14
+ const canonical = process.platform === 'win32' ? workspace.toLowerCase() : workspace;
15
+ const authorityFile = path.join(workspace, '.agents', 'runtime', 'generation.json');
16
+ let selected;
17
+ try { selected = JSON.parse(fs.readFileSync(authorityFile, 'utf8')); }
18
+ catch (error) {
19
+ if (error.code !== 'ENOENT') throw error;
20
+ // Migration only: the workspace pin is explicit, never the machine's
21
+ // latest pointer or a release inferred from deployed resource version.
22
+ selected = JSON.parse(fs.readFileSync(path.join(root, 'workspaces',
23
+ crypto.createHash('sha256').update(canonical).digest('hex') + '.json'), 'utf8'));
24
+ }
25
+ if (selected.workspace && (process.platform === 'win32' ? selected.workspace.toLowerCase() : selected.workspace) !== canonical)
26
+ throw Error('HOOK_WORKSPACE_BINDING_CONFLICT');
27
+ if (!/^\d+\.\d+\.\d+$/.test(selected.version) || !/^[a-f0-9]{64}$/.test(selected.digest))
28
+ throw Error('HOOK_RUNTIME_BINDING_REQUIRED');
29
+ const release = path.join(root, 'releases', `${selected.version}-${selected.digest}`);
30
+ if (fs.lstatSync(release).isSymbolicLink()) throw Error('HOOK_RUNTIME_LINK_REJECTED');
31
+ const manifest = JSON.parse(fs.readFileSync(path.join(release, 'integrity-manifest.json'), 'utf8'));
32
+ if (crypto.createHash('sha256').update(JSON.stringify(manifest)).digest('hex') !== selected.digest ||
33
+ !crypto.verify(null, Buffer.from(JSON.stringify(manifest.files)), publicKey, Buffer.from(manifest.signature, 'base64url')))
34
+ throw Error('HOOK_RUNTIME_SIGNATURE_INVALID');
35
+ for (const required of ['src/core/hook-bridge.js'])
36
+ if (!manifest.files[required]) throw Error('HOOK_RUNTIME_RECONNECT_REQUIRED');
37
+ for (const [file, digest] of Object.entries(manifest.files)) {
38
+ if (path.isAbsolute(file) || file.includes('\\') || file.split('/').some(part => !part || part === '..' || part === '.'))
39
+ throw Error('HOOK_RUNTIME_PATH_INVALID');
40
+ let cursor = release;
41
+ for (const part of file.split('/')) {
42
+ cursor = path.join(cursor, part);
43
+ if (fs.lstatSync(cursor).isSymbolicLink()) throw Error('HOOK_RUNTIME_LINK_REJECTED');
44
+ }
45
+ if (crypto.createHash('sha256').update(fs.readFileSync(cursor)).digest('hex') !== digest)
46
+ throw Error('HOOK_RUNTIME_INTEGRITY_INVALID');
47
+ }
48
+ return require(path.join(release, 'src/core/hook-bridge.js')).runCLI(host, event,
49
+ Buffer.from(workspace, 'utf8').toString('base64'), executionOptions);
50
+ } };
51
+ }
52
+
53
+ // The parent only uses built-ins. Synchronous hashing/locks in the signed
54
+ // worker cannot prevent the parent from producing a blocking decision.
55
+ function superviseHook(root, publicKey, dispatcherSource, args, timeoutMs, passive) {
56
+ const cp = require('node:child_process'), crypto = require('node:crypto');
57
+ const lease = { id: crypto.randomUUID(), notAfter: Date.now() + timeoutMs, maxDurationMs: timeoutMs };
58
+ // The worker lives for one host event. APT_HOOK_PROCESS lets its runtime
59
+ // locks record a start hint instead of starting PowerShell on every tool call.
60
+ const program = `process.env.APT_HOOK_PROCESS = '1';
61
+ const dispatcher = (${dispatcherSource})(${JSON.stringify(root)}, ${JSON.stringify(publicKey)});
62
+ process.once('message', async message => {
63
+ try { await dispatcher.runCLI(...message.args, { hookLease: message.lease }); }
64
+ catch (error) { process.stderr.write('APT hook: ' + (error.message || String(error)) + '\\n'); process.exitCode = 2; }
65
+ finally { if (process.connected) process.disconnect(); }
66
+ });`;
67
+ return new Promise((resolve, reject) => {
68
+ let settled = false, output = '', errors = '', inputBytes = 0;
69
+ const received = [];
70
+ // APT allows a passive host read in every session state. A fault of APT
71
+ // itself, a missed deadline above all, must not refuse one. The answer is
72
+ // the output that lets the call proceed, or null for every other call.
73
+ const allowance = () => {
74
+ try {
75
+ const table = passive && passive[args[0]];
76
+ const allow = table && table.events[args[1]];
77
+ if (typeof allow !== 'string') return null;
78
+ const input = JSON.parse(Buffer.concat(received).toString('utf8'));
79
+ const name = input.tool_name;
80
+ if (typeof name !== 'string' || input.toolCall !== undefined || input.userStopped === true) return null;
81
+ return table.exact.includes(name) || table.insensitive.includes(name.toLowerCase()) ? allow : null;
82
+ } catch { return null; }
83
+ };
84
+ const child = cp.spawn(process.execPath, ['-e', program], { windowsHide: true, stdio: ['pipe', 'pipe', 'pipe', 'ipc'] });
85
+ const detach = () => {
86
+ clearTimeout(timer); process.stdin.unpipe(child.stdin); process.stdin.removeListener('data', countInput);
87
+ child.stdin.destroy();
88
+ };
89
+ const fail = code => {
90
+ if (settled) return;
91
+ settled = true; detach();
92
+ if (child.connected) child.disconnect();
93
+ child.kill(); child.stdout.destroy(); child.stderr.destroy(); child.unref();
94
+ const allow = allowance();
95
+ if (allow === null) return reject(new Error(code));
96
+ process.stderr.write('APT hook: ' + code + ' (not refused)\n');
97
+ process.stdout.write(allow + '\n');
98
+ process.exitCode = 0;
99
+ resolve();
100
+ };
101
+ const countInput = chunk => {
102
+ inputBytes += chunk.length;
103
+ if (inputBytes > 2 * 1024 * 1024) fail('HOOK_INPUT_LIMIT'); else received.push(Buffer.from(chunk));
104
+ };
105
+ const timer = setTimeout(() => fail('HOOK_DEADLINE_EXCEEDED'), timeoutMs);
106
+ child.on('error', () => fail('HOOK_WORKER_UNAVAILABLE'));
107
+ child.stdin.on('error', () => {});
108
+ child.stdout.on('data', chunk => { output += chunk.toString(); if (Buffer.byteLength(output) > 2 * 1024 * 1024) fail('HOOK_OUTPUT_LIMIT'); });
109
+ child.stderr.on('data', chunk => { errors += chunk.toString(); if (Buffer.byteLength(errors) > 64 * 1024) fail('HOOK_OUTPUT_LIMIT'); });
110
+ child.on('close', code => {
111
+ if (settled) return;
112
+ if (Date.now() >= lease.notAfter) return fail('HOOK_DEADLINE_EXCEEDED');
113
+ settled = true; detach();
114
+ // A worker that failed before the bridge could decide refuses nothing
115
+ // that APT always allows.
116
+ const allow = code === 0 ? null : allowance();
117
+ if (code === 0) { if (output) process.stdout.write(output); }
118
+ if (errors) process.stderr.write(errors);
119
+ if (allow !== null) process.stdout.write(allow + '\n');
120
+ process.exitCode = code === 0 || allow !== null ? 0 : 2;
121
+ resolve();
122
+ });
123
+ process.stdin.on('data', countInput); process.stdin.pipe(child.stdin);
124
+ child.send({ args, lease }, error => { if (error) fail('HOOK_WORKER_UNAVAILABLE'); });
125
+ });
126
+ }
127
+
128
+ // Only a pre-tool decision may block its host. Any other event observes
129
+ // something that already happened, so a dispatcher or runtime fault there is a
130
+ // non-blocking error: it must not reject a prompt or force a continuation.
131
+ function blockingEvents() {
132
+ const { HOSTS } = require('../core/host-adapters');
133
+ return Object.fromEntries(Object.entries(HOSTS).map(([host, adapter]) =>
134
+ [host, Object.keys(adapter.events).filter(event => adapter.events[event] === 'before-tool')]));
135
+ }
136
+
137
+ // For each host: the events that guard a tool call, each with the output
138
+ // that lets the call proceed, and the tools APT allows in every session state.
139
+ function passiveReads() {
140
+ const { HOSTS, formatHookResult } = require('../core/host-adapters');
141
+ const { passiveHostTools } = require('../core/hook-bridge');
142
+ return Object.fromEntries(Object.entries(HOSTS).map(([host, adapter]) => [host, {
143
+ events: Object.fromEntries(Object.keys(adapter.events).filter(event => adapter.events[event] === 'before-tool')
144
+ .map(event => [event, JSON.stringify(formatHookResult(host, event, { allow: true }).output)])),
145
+ ...passiveHostTools(host) }]));
146
+ }
147
+
148
+ function renderDispatcher(runtimeRoot, publicKey, options = {}) {
149
+ const timeoutMs = options.timeoutMs === undefined ? 10000 : options.timeoutMs;
150
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 10000) throw new Error('HOOK_DEADLINE_INVALID');
151
+ return `'use strict';
152
+ const dispatcher = (${hookDispatcher.toString()})(${JSON.stringify(runtimeRoot)}, ${JSON.stringify(publicKey.toString())});
153
+ const blockingEvents = ${JSON.stringify(blockingEvents())};
154
+ // An unknown host or event stays blocking.
155
+ const failureCode = args => !blockingEvents[args[0]] || blockingEvents[args[0]].includes(args[1]) ? 2 : 1;
156
+ function reportFailure(error, args) {
157
+ process.stderr.write('APT hook: ' + (error && error.message ? error.message : String(error)) + '\\n');
158
+ process.exitCode = failureCode(args);
159
+ }
160
+ module.exports = { runCLI(...args) {
161
+ try {
162
+ // Generated host commands use node --eval. Direct verifier consumers keep
163
+ // the synchronous interface; host execution always has an outer watchdog.
164
+ const hostCLI = process.argv.length === 1 && process.execArgv.some(arg => arg === '-e' || arg === '--eval');
165
+ const result = hostCLI
166
+ ? (${superviseHook.toString()})(${JSON.stringify(runtimeRoot)}, ${JSON.stringify(publicKey.toString())}, ${JSON.stringify(hookDispatcher.toString())}, args, ${timeoutMs}, ${JSON.stringify(passiveReads())})
167
+ : dispatcher.runCLI(...args);
168
+ if (result && typeof result.then === 'function')
169
+ result.then(() => { if (hostCLI && process.exitCode) process.exitCode = failureCode(args); },
170
+ error => reportFailure(error, args));
171
+ return result;
172
+ } catch (error) {
173
+ reportFailure(error, args);
174
+ }
175
+ } };
176
+ `;
177
+ }
178
+
179
+ module.exports = { hookDispatcher, renderDispatcher };
@@ -1 +1 @@
1
- const _0x413bae=_0x44a1;function _0x3fa7(){const _0x409d32=['zMLSDgvY','BgL2zvzLCMLMAwvK','otLNrg1mufu','Aw5ZDgfSBeHVC3riB29RCW','D2LUzhn1CMy','mZyZndK4nvzOwffiyq','mtiWmZuYmMfRvuXqBW','C3rHDhvZ','y2XHDwrL','D3jPDgvgAwXLu3LUyW','oYbVCMLNAw5HBcbMAwXLihDHCYbWCMvZzxj2zwq6ia','y29KzxG','mZy3mdi4ngnLENziyq','y29TBwfUza','Cgf0Aa','C3rYAw5NAwz5','CMvJDxjZAxzL','DxrMoa','lI9Tyw5Hz2vKlwnVBMzPzW','BwTKAxjtEw5J','BwvZC2fNzq','BM9KzsaTzsaI','qvbux0Hpt0TFqLjjreDf','BM9KzsaTzsaIlYPbufrFse9ps19cuKLer0uQlW','BwvYz2viB29RCW','Ag9ZDa','Aw5JBhvKzxm','odK1mJKZEgDLENLh','lI4Vy29Yzs9OB3n0lwfKyxb0zxjZ','nde0rePUrMHw','ChvZAa','B2jQzwn0','A2v5CW','lMfNzw50CY9JB3jLl2HVB2STyNjPzgDLlMPZ','mJyXn1fKDLr0yW','yw50AwDYyxzPDhK','zxHPC3rZu3LUyW','CMvZB2X2zq','y2XHDwrLlwrLC2T0B3a','CMvWBgfJzq','CMvSyxrPDMu','C29Tzq','mJG5ode2qxrnvM9R','zw50CMLLCW','y29Kzq','AM9PBG','sw52ywXPzcbJB25MAwCGyxqG','odm2mdG0swPSvez6','CgfYC2u','su5wquXjrf9dt05gsuC','ChvIBgLJs2v5','zgLYBMfTzq','CMvHzezPBgvtEw5J','C3rHCNrZv2L0Aa','ChjVDg9JB2Xuzxn0zwq','y3vYC29Y'];_0x3fa7=function(){return _0x409d32;};return _0x3fa7();}(function(_0x26b785,_0x527cb3){const _0x4ec23d=_0x44a1,_0x451fcc=_0x26b785();while(!![]){try{const _0x57aee9=-parseInt(_0x4ec23d(0x10e))/0x1*(parseInt(_0x4ec23d(0x109))/0x2)+parseInt(_0x4ec23d(0x12a))/0x3+parseInt(_0x4ec23d(0x11b))/0x4+parseInt(_0x4ec23d(0x129))/0x5+-parseInt(_0x4ec23d(0x130))/0x6+-parseInt(_0x4ec23d(0x107))/0x7+-parseInt(_0x4ec23d(0x116))/0x8*(-parseInt(_0x4ec23d(0x126))/0x9);if(_0x57aee9===_0x527cb3)break;else _0x451fcc['push'](_0x451fcc['shift']());}catch(_0x3ba9e7){_0x451fcc['push'](_0x451fcc['shift']());}}}(_0x3fa7,0x6eed5));function _0x44a1(_0x5b8c2b,_0x5854d5){_0x5b8c2b=_0x5b8c2b-0x100;const _0x3fa7c4=_0x3fa7();let _0x44a123=_0x3fa7c4[_0x5b8c2b];if(_0x44a1['hbQjfS']===undefined){var _0x39d301=function(_0x5ac045){const _0x10c692='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x21dc3c='',_0xe0b2f4='';for(let _0x121493=0x0,_0x41f7a0,_0x374938,_0x2bab3a=0x0;_0x374938=_0x5ac045['charAt'](_0x2bab3a++);~_0x374938&&(_0x41f7a0=_0x121493%0x4?_0x41f7a0*0x40+_0x374938:_0x374938,_0x121493++%0x4)?_0x21dc3c+=String['fromCharCode'](0xff&_0x41f7a0>>(-0x2*_0x121493&0x6)):0x0){_0x374938=_0x10c692['indexOf'](_0x374938);}for(let _0x6accda=0x0,_0x5c43a4=_0x21dc3c['length'];_0x6accda<_0x5c43a4;_0x6accda++){_0xe0b2f4+='%'+('00'+_0x21dc3c['charCodeAt'](_0x6accda)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xe0b2f4);};_0x44a1['vHzZeC']=_0x39d301,_0x44a1['ZmgFqy']={},_0x44a1['hbQjfS']=!![];}const _0xa19025=_0x3fa7c4[0x0],_0x4805b6=_0x5b8c2b+_0xa19025,_0x33d2b6=_0x44a1['ZmgFqy'][_0x4805b6];return!_0x33d2b6?(_0x44a123=_0x44a1['vHzZeC'](_0x44a123),_0x44a1['ZmgFqy'][_0x4805b6]=_0x44a123):_0x44a123=_0x33d2b6,_0x44a123;}const fs=require('fs'),path=require(_0x413bae(0x132)),{buildHookConfig}=require(_0x413bae(0x108)),{readJsonWithBackup,parseJson}=require(_0x413bae(0x136));function mergeHooks(_0x6accda,_0x5c43a4){const _0x1134ce=_0x413bae;if(Array['isArray'](_0x5c43a4)){const _0x1cbf9a=(Array['isArray'](_0x6accda)?_0x6accda:[])['filter'](_0x59e45a=>!JSON[_0x1134ce(0x133)](_0x59e45a)[_0x1134ce(0x106)](_0x1134ce(0x102)));return[..._0x1cbf9a,..._0x5c43a4];}if(_0x5c43a4&&typeof _0x5c43a4===_0x1134ce(0x10b)){const _0x15c265={..._0x6accda&&typeof _0x6accda===_0x1134ce(0x10b)?_0x6accda:{}},_0x2644d0=_0x15c265;for(const [_0x5ad08f,_0x220d5d]of Object[_0x1134ce(0x117)](_0x5c43a4)){const _0x38fc50=Array['isArray'](_0x220d5d)&&!JSON[_0x1134ce(0x133)](_0x2644d0[_0x5ad08f]??'')[_0x1134ce(0x106)](_0x1134ce(0x102))&&Object[_0x1134ce(0x117)](_0x2644d0)[_0x1134ce(0x115)](([_0x3eb471,_0x5f2716])=>_0x3eb471[_0x1134ce(0x121)](_0x5ad08f+'_')&&JSON[_0x1134ce(0x133)](_0x5f2716)[_0x1134ce(0x106)]('APT_HOOK_BRIDGE'));if(!_0x38fc50)_0x2644d0[_0x5ad08f]=mergeHooks(_0x2644d0[_0x5ad08f],_0x220d5d);}return _0x2644d0;}return _0x5c43a4;}function installHostHooks(_0x47644e,_0x139c39=null,_0x541f14={}){const _0x1eeec8=_0x413bae,_0x58e4e0=_0x541f14['fileSystem']||fs,_0x1011ad={};_0x1011ad['codex']=_0x1eeec8(0x12f),_0x1011ad[_0x1eeec8(0x12c)]='claude-code',_0x1011ad['cursor']=_0x1eeec8(0x123),_0x1011ad[_0x1eeec8(0x10f)]=_0x1eeec8(0x10f),_0x1011ad['vscode']='vscode-copilot',_0x1011ad['windsurf']=_0x1eeec8(0x128),_0x1011ad[_0x1eeec8(0x112)]=_0x1eeec8(0x112);const _0x1d0475=_0x1011ad;let _0x37c44a=path[_0x1eeec8(0x119)](_0x47644e,_0x1eeec8(0x10d));if(!_0x58e4e0[_0x1eeec8(0x110)](_0x37c44a))return[];if(_0x541f14['runtimeRoot']&&_0x541f14[_0x1eeec8(0x11e)]){_0x37c44a=path['join'](_0x47644e,'.agents/core/hook-dispatcher.js');const _0x3f56ec=require('./hook-dispatcher')['renderDispatcher'](_0x541f14['runtimeRoot'],_0x541f14[_0x1eeec8(0x11e)]);if(!_0x58e4e0['existsSync'](_0x37c44a)||_0x58e4e0[_0x1eeec8(0x120)](_0x37c44a,_0x1eeec8(0x135))!==_0x3f56ec)_0x58e4e0[_0x1eeec8(0x12d)](_0x37c44a,_0x3f56ec);}const _0x17558a=[];for(const _0x955bd6 of _0x139c39||Object[_0x1eeec8(0x10c)](_0x1d0475)[_0x1eeec8(0x124)](_0x19feaf=>_0x19feaf!=='claude-desktop')){const _0x4e0e74=buildHookConfig(_0x1d0475[_0x955bd6]||_0x955bd6,_0x37c44a,_0x47644e);if(!_0x4e0e74?.[_0x1eeec8(0x132)]||!_0x4e0e74['config']||_0x4e0e74['advisory'])continue;const _0x34a285=path[_0x1eeec8(0x111)](_0x47644e,_0x4e0e74[_0x1eeec8(0x132)]);if(path[_0x1eeec8(0x114)](_0x47644e,_0x34a285)[_0x1eeec8(0x121)]('..'))throw new Error('Hook\x20config\x20path\x20escapes\x20project');const _0x12305c=JSON[_0x1eeec8(0x11c)](JSON[_0x1eeec8(0x133)](_0x4e0e74['config']),(_0x9651dd,_0x16ab79)=>{const _0x326769=_0x1eeec8;if(_0x9651dd===_0x326769(0x131)&&typeof _0x16ab79==='string'&&_0x16ab79[_0x326769(0x121)]('node\x20-e\x20')&&!_0x16ab79[_0x326769(0x106)](_0x326769(0x102)))return _0x16ab79[_0x326769(0x113)](_0x326769(0x101),_0x326769(0x103));return _0x16ab79;});let _0xe78a3b;if(!_0x541f14['fileSystem'])_0xe78a3b=readJsonWithBackup(_0x34a285);else{if(!_0x58e4e0[_0x1eeec8(0x110)](_0x34a285))_0xe78a3b={};else try{_0xe78a3b=parseJson(_0x58e4e0[_0x1eeec8(0x120)](_0x34a285,_0x1eeec8(0x135)));}catch(_0x19aa6c){const _0x2604fe={};_0x2604fe[_0x1eeec8(0x118)]=_0x1eeec8(0x11d);throw Object['assign'](new Error(_0x1eeec8(0x11a)+_0x34a285+_0x1eeec8(0x12e)+_0x19aa6c[_0x1eeec8(0x100)]),_0x2604fe);}}const _0x3f691d=mergeHooks(_0xe78a3b,_0x12305c),_0x4c1377={};_0x4c1377[_0x1eeec8(0x134)]=!![],_0x58e4e0[_0x1eeec8(0x137)](path[_0x1eeec8(0x11f)](_0x34a285),_0x4c1377),_0x58e4e0[_0x1eeec8(0x12d)](_0x34a285,JSON['stringify'](_0x3f691d,null,0x2)+'\x0a');const _0x7258ea={};_0x7258ea[_0x1eeec8(0x105)]=_0x955bd6,_0x7258ea[_0x1eeec8(0x132)]=_0x4e0e74[_0x1eeec8(0x132)],_0x7258ea[_0x1eeec8(0x122)]=![],_0x7258ea[_0x1eeec8(0x125)]=![],_0x7258ea[_0x1eeec8(0x12b)]='installed-unobserved',_0x17558a[_0x1eeec8(0x10a)](_0x7258ea);}return _0x17558a;}const _0x2bab3a={};_0x2bab3a[_0x413bae(0x127)]=installHostHooks,_0x2bab3a[_0x413bae(0x104)]=mergeHooks,module['exports']=_0x2bab3a;
1
+ const _0x3b39ef=_0x314b;(function(_0x575461,_0x1d6146){const _0xe3bd2d=_0x314b,_0x2f36e1=_0x575461();while(!![]){try{const _0x1cebbe=-parseInt(_0xe3bd2d(0x1ec))/0x1+parseInt(_0xe3bd2d(0x1d8))/0x2+-parseInt(_0xe3bd2d(0x1d5))/0x3*(-parseInt(_0xe3bd2d(0x1ed))/0x4)+-parseInt(_0xe3bd2d(0x1f3))/0x5*(-parseInt(_0xe3bd2d(0x1de))/0x6)+-parseInt(_0xe3bd2d(0x1db))/0x7+-parseInt(_0xe3bd2d(0x1df))/0x8+-parseInt(_0xe3bd2d(0x1f4))/0x9*(-parseInt(_0xe3bd2d(0x1fd))/0xa);if(_0x1cebbe===_0x1d6146)break;else _0x2f36e1['push'](_0x2f36e1['shift']());}catch(_0x4674a9){_0x2f36e1['push'](_0x2f36e1['shift']());}}}(_0x530d,0xc8831));const fs=require('fs'),path=require(_0x3b39ef(0x204)),{buildHookConfig}=require(_0x3b39ef(0x1eb)),{readJsonWithBackup,parseJson}=require(_0x3b39ef(0x201));function mergeHooks(_0x61db91,_0x462a15){const _0x35e53c=_0x3b39ef;if(Array[_0x35e53c(0x1f9)](_0x462a15)){const _0x86fa25=(Array[_0x35e53c(0x1f9)](_0x61db91)?_0x61db91:[])['filter'](_0x22aa64=>!JSON['stringify'](_0x22aa64)[_0x35e53c(0x209)](_0x35e53c(0x1ff)));return[..._0x86fa25,..._0x462a15];}if(_0x462a15&&typeof _0x462a15===_0x35e53c(0x1d6)){const _0x44a2de={..._0x61db91&&typeof _0x61db91==='object'?_0x61db91:{}},_0x2031df=_0x44a2de;for(const [_0x518295,_0x3a3cf6]of Object[_0x35e53c(0x20f)](_0x462a15)){const _0x14aef0=Array[_0x35e53c(0x1f9)](_0x3a3cf6)&&!JSON[_0x35e53c(0x1fc)](_0x2031df[_0x518295]??'')['includes']('APT_HOOK_BRIDGE')&&Object['entries'](_0x2031df)[_0x35e53c(0x202)](([_0x330867,_0x586a4e])=>_0x330867[_0x35e53c(0x1d3)](_0x518295+'_')&&JSON['stringify'](_0x586a4e)[_0x35e53c(0x209)](_0x35e53c(0x1ff)));if(!_0x14aef0)_0x2031df[_0x518295]=mergeHooks(_0x2031df[_0x518295],_0x3a3cf6);}return _0x2031df;}return _0x462a15;}function installHostHooks(_0x4d2a58,_0x3cc7bb=null,_0x471096={}){const _0xa0f5d3=_0x3b39ef,_0x4bf5de=_0x471096[_0xa0f5d3(0x208)]||fs,_0x5707e7={};_0x5707e7[_0xa0f5d3(0x1fb)]=_0xa0f5d3(0x1fb),_0x5707e7[_0xa0f5d3(0x1ea)]=_0xa0f5d3(0x1e2),_0x5707e7['cursor']=_0xa0f5d3(0x1e8),_0x5707e7['antigravity']=_0xa0f5d3(0x1dc),_0x5707e7[_0xa0f5d3(0x1f0)]='vscode-copilot',_0x5707e7[_0xa0f5d3(0x20c)]=_0xa0f5d3(0x20c),_0x5707e7[_0xa0f5d3(0x1fe)]=_0xa0f5d3(0x1fe);const _0xb4c1b7=_0x5707e7;let _0x318764=path[_0xa0f5d3(0x1e5)](_0x4d2a58,_0xa0f5d3(0x1ef));if(!_0x4bf5de[_0xa0f5d3(0x1e3)](_0x318764))return[];if(_0x471096[_0xa0f5d3(0x1f5)]&&_0x471096[_0xa0f5d3(0x203)]){_0x318764=path[_0xa0f5d3(0x1e5)](_0x4d2a58,'.agents/core/hook-dispatcher.js');const _0xeb248=require(_0xa0f5d3(0x1e1))['renderDispatcher'](_0x471096[_0xa0f5d3(0x1f5)],_0x471096[_0xa0f5d3(0x203)]);if(!_0x4bf5de[_0xa0f5d3(0x1e3)](_0x318764)||_0x4bf5de[_0xa0f5d3(0x20d)](_0x318764,_0xa0f5d3(0x20a))!==_0xeb248)_0x4bf5de[_0xa0f5d3(0x1e7)](_0x318764,_0xeb248);}const _0x3cc78b=[];for(const _0x10210f of _0x3cc7bb||Object['keys'](_0xb4c1b7)[_0xa0f5d3(0x20e)](_0x8a9272=>_0x8a9272!=='claude-desktop')){const _0x3fb3da=buildHookConfig(_0xb4c1b7[_0x10210f]||_0x10210f,_0x318764,_0x4d2a58);if(!_0x3fb3da?.[_0xa0f5d3(0x204)]||!_0x3fb3da[_0xa0f5d3(0x20b)]||_0x3fb3da[_0xa0f5d3(0x1e4)])continue;const _0x30d3ae=path[_0xa0f5d3(0x1dd)](_0x4d2a58,_0x3fb3da['path']);if(path[_0xa0f5d3(0x200)](_0x4d2a58,_0x30d3ae)['startsWith']('..'))throw new Error(_0xa0f5d3(0x207));const _0x266c4f=JSON[_0xa0f5d3(0x1f8)](JSON[_0xa0f5d3(0x1fc)](_0x3fb3da['config']),(_0x27c738,_0x1311c0)=>{const _0x33804b=_0xa0f5d3;if(_0x27c738===_0x33804b(0x1fa)&&typeof _0x1311c0===_0x33804b(0x1f7)&&_0x1311c0[_0x33804b(0x1d3)](_0x33804b(0x1ee))&&!_0x1311c0[_0x33804b(0x209)](_0x33804b(0x1ff)))return _0x1311c0['replace'](_0x33804b(0x206),_0x33804b(0x1d7));return _0x1311c0;});let _0x446082;if(!_0x471096[_0xa0f5d3(0x208)])_0x446082=readJsonWithBackup(_0x30d3ae);else{if(!_0x4bf5de[_0xa0f5d3(0x1e3)](_0x30d3ae))_0x446082={};else try{_0x446082=parseJson(_0x4bf5de[_0xa0f5d3(0x20d)](_0x30d3ae,'utf8'));}catch(_0x45f9aa){const _0x5db49e={};_0x5db49e['code']=_0xa0f5d3(0x1e0);throw Object['assign'](new Error('Invalid\x20config\x20at\x20'+_0x30d3ae+';\x20original\x20file\x20was\x20preserved:\x20'+_0x45f9aa[_0xa0f5d3(0x1f6)]),_0x5db49e);}}const _0x285820=mergeHooks(_0x446082,_0x266c4f),_0xa96398={};_0xa96398[_0xa0f5d3(0x1da)]=!![],_0x4bf5de['mkdirSync'](path[_0xa0f5d3(0x1d4)](_0x30d3ae),_0xa96398),_0x4bf5de[_0xa0f5d3(0x1e7)](_0x30d3ae,JSON['stringify'](_0x285820,null,0x2)+'\x0a');const _0x42f98e={};_0x42f98e[_0xa0f5d3(0x1f2)]=_0x10210f,_0x42f98e[_0xa0f5d3(0x204)]=_0x3fb3da['path'],_0x42f98e[_0xa0f5d3(0x205)]=![],_0x42f98e[_0xa0f5d3(0x1f1)]=![],_0x42f98e[_0xa0f5d3(0x1e9)]='installed-unobserved',_0x3cc78b[_0xa0f5d3(0x1e6)](_0x42f98e);}return _0x3cc78b;}function _0x314b(_0x54fe93,_0x1bcea5){_0x54fe93=_0x54fe93-0x1d3;const _0x530d48=_0x530d();let _0x314b68=_0x530d48[_0x54fe93];if(_0x314b['cSwDoq']===undefined){var _0x17a11b=function(_0x42d780){const _0x2238d1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xfd02cb='',_0x22ee82='';for(let _0x6c2713=0x0,_0x515b04,_0x517145,_0x17251e=0x0;_0x517145=_0x42d780['charAt'](_0x17251e++);~_0x517145&&(_0x515b04=_0x6c2713%0x4?_0x515b04*0x40+_0x517145:_0x517145,_0x6c2713++%0x4)?_0xfd02cb+=String['fromCharCode'](0xff&_0x515b04>>(-0x2*_0x6c2713&0x6)):0x0){_0x517145=_0x2238d1['indexOf'](_0x517145);}for(let _0x61db91=0x0,_0x462a15=_0xfd02cb['length'];_0x61db91<_0x462a15;_0x61db91++){_0x22ee82+='%'+('00'+_0xfd02cb['charCodeAt'](_0x61db91)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x22ee82);};_0x314b['HBVjkj']=_0x17a11b,_0x314b['JVazQZ']={},_0x314b['cSwDoq']=!![];}const _0x811710=_0x530d48[0x0],_0x3dbdb8=_0x54fe93+_0x811710,_0x187dac=_0x314b['JVazQZ'][_0x3dbdb8];return!_0x187dac?(_0x314b68=_0x314b['HBVjkj'](_0x314b68),_0x314b['JVazQZ'][_0x3dbdb8]=_0x314b68):_0x314b68=_0x187dac,_0x314b68;}const _0x17251e={};_0x17251e[_0x3b39ef(0x1d9)]=installHostHooks,_0x17251e['mergeHooks']=mergeHooks,module['exports']=_0x17251e;function _0x530d(){const _0x37c9f4=['C3rYAw5N','CgfYC2u','AxnbCNjHEq','y29TBwfUza','y29KzxG','C3rYAw5NAwz5','mtiWrKTxCer6','y2XHDwrLlwrLC2T0B3a','qvbux0Hpt0TFqLjjreDf','CMvSyxrPDMu','lI9Tyw5Hz2vKlwnVBMzPzW','C29Tzq','ChvIBgLJs2v5','Cgf0Aa','ChjVDg9JB2Xuzxn0zwq','BM9KzsaTzsaI','sg9VAYbJB25MAwCGCgf0AcbLC2nHCgvZihbYB2PLy3q','zMLSzvn5C3rLBq','Aw5JBhvKzxm','DxrMoa','y29UzMLN','D2LUzhn1CMy','CMvHzezPBgvtEw5J','zMLSDgvY','zw50CMLLCW','C3rHCNrZv2L0Aa','zgLYBMfTzq','mJe0mJnQvgTtuuy','B2jQzwn0','BM9KzsaTzsaIlYPbufrFse9ps19cuKLer0uQlW','mZiYodKWqM50Exb3','Aw5ZDgfSBeHVC3riB29RCW','CMvJDxjZAxzL','mJu5mZGWoe9ssLLeCq','yw50AwDYyxzPDhK','CMvZB2X2zq','nZKXndaWnKLbBLfPva','mJa1mJHrrg91z3y','su5wquXjrf9dt05gsuC','lI9OB29RlwrPC3bHDgnOzxi','y2XHDwrLlwnVzgu','zxHPC3rZu3LUyW','ywr2AxnVCNK','AM9PBG','ChvZAa','D3jPDgvgAwXLu3LUyW','y3vYC29Y','C3rHDhvZ','y2XHDwrL','lI4Vy29Yzs9OB3n0lwfKyxb0zxjZ','mte2nZe3nK5gB3ntsq','ntjxAefWuee','BM9KzsaTzsa','lMfNzw50CY9JB3jLl2HVB2STyNjPzgDLlMPZ','DNnJB2rL','BgL2zvzLCMLMAwvK','Ag9ZDa','nvjJsNr6Ea','ntKXmJi4zunorfLI','CNvUDgLTzvjVB3q','BwvZC2fNzq'];_0x530d=function(){return _0x37c9f4;};return _0x530d();}