codehere 0.8.0 → 1.0.2
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/README.md +37 -184
- package/dist/application/use-cases/check-claimed-tests.js +81 -0
- package/dist/application/use-cases/detect-test-weakening.js +237 -0
- package/dist/application/use-cases/rerun-tests.js +329 -0
- package/dist/index.js +74 -1004
- package/dist/infrastructure/orchestration/artifacts-extractor.js +2 -265
- package/dist/presentation/cli/commands/check-command.js +251 -0
- package/dist/presentation/cli/commands/help-command.js +22 -286
- package/dist/ui.js +19 -438
- package/dist/utils/version.js +0 -12
- package/package.json +18 -27
- package/dist/application/use-cases/domain-trust.js +0 -110
- package/dist/application/use-cases/generate-final-report.js +0 -134
- package/dist/application/use-cases/generate-narration.js +0 -128
- package/dist/application/use-cases/generate-thread-title.js +0 -178
- package/dist/application/use-cases/narrator-prompt-template.js +0 -158
- package/dist/application/use-cases/thread-export.js +0 -155
- package/dist/application/use-cases/verify-claim.js +0 -274
- package/dist/application/use-cases/write-pass.js +0 -277
- package/dist/domain/entities/task.js +0 -61
- package/dist/domain/services/codebase-detector.js +0 -91
- package/dist/error-handler.js +0 -251
- package/dist/infrastructure/completion/bash-completion.js +0 -25
- package/dist/infrastructure/completion/fish-completion.js +0 -22
- package/dist/infrastructure/completion/zsh-completion.js +0 -30
- package/dist/infrastructure/config/config-manager.js +0 -173
- package/dist/infrastructure/config/product-context.js +0 -67
- package/dist/infrastructure/context/adapters/drawio-source.js +0 -157
- package/dist/infrastructure/context/adapters/figma-source.js +0 -163
- package/dist/infrastructure/context/adapters/github-issue-source.js +0 -159
- package/dist/infrastructure/context/adapters/linear-source.js +0 -190
- package/dist/infrastructure/context/context-resolver.js +0 -144
- package/dist/infrastructure/context/context-source.js +0 -114
- package/dist/infrastructure/context/oauth-flow.js +0 -207
- package/dist/infrastructure/context/oauth-store.js +0 -119
- package/dist/infrastructure/context/registry-bootstrap.js +0 -99
- package/dist/infrastructure/context/write-pass-resolver.js +0 -106
- package/dist/infrastructure/cost/budget-config.js +0 -113
- package/dist/infrastructure/cost/cost-router.js +0 -104
- package/dist/infrastructure/cost/spend-aggregator.js +0 -147
- package/dist/infrastructure/hooks/claude-sdk-hook.js +0 -888
- package/dist/infrastructure/hooks/hook-mode.js +0 -71
- package/dist/infrastructure/hooks/mirror-tool-call-to-audit.js +0 -43
- package/dist/infrastructure/hooks/pre-prompt-scan.js +0 -122
- package/dist/infrastructure/hooks/session-analyzer.js +0 -177
- package/dist/infrastructure/observability/execution-tracer.js +0 -227
- package/dist/infrastructure/orchestration/agent-adapter.js +0 -13
- package/dist/infrastructure/orchestration/agent-installer.js +0 -101
- package/dist/infrastructure/orchestration/agents-config-seed.js +0 -56
- package/dist/infrastructure/orchestration/aider-adapter.js +0 -447
- package/dist/infrastructure/orchestration/cassette-recorder.js +0 -120
- package/dist/infrastructure/orchestration/claude-code-adapter.js +0 -478
- package/dist/infrastructure/orchestration/codex-adapter.js +0 -538
- package/dist/infrastructure/orchestration/conductor-adapter.js +0 -377
- package/dist/infrastructure/orchestration/context-handoff.js +0 -144
- package/dist/infrastructure/orchestration/control/codex-control-surface.js +0 -99
- package/dist/infrastructure/orchestration/control/control-surface.js +0 -15
- package/dist/infrastructure/orchestration/failover-classifier.js +0 -151
- package/dist/infrastructure/orchestration/failover-config.js +0 -77
- package/dist/infrastructure/orchestration/failover-policy.js +0 -106
- package/dist/infrastructure/orchestration/gemini-adapter.js +0 -583
- package/dist/infrastructure/orchestration/generic-cli-adapter.js +0 -558
- package/dist/infrastructure/orchestration/graphify-context.js +0 -254
- package/dist/infrastructure/orchestration/memory-injector.js +0 -380
- package/dist/infrastructure/orchestration/mocks/mock-agent-repl.js +0 -233
- package/dist/infrastructure/orchestration/mocks/mock-codex-app-server.js +0 -73
- package/dist/infrastructure/orchestration/mocks/mock-synthesis.js +0 -83
- package/dist/infrastructure/orchestration/mocks/resolve-agent-spawn.js +0 -37
- package/dist/infrastructure/orchestration/opencode-adapter.js +0 -510
- package/dist/infrastructure/orchestration/progress-aggregator.js +0 -689
- package/dist/infrastructure/orchestration/readiness.js +0 -103
- package/dist/infrastructure/orchestration/session-manager.js +0 -1091
- package/dist/infrastructure/orchestration/session-persistence.js +0 -258
- package/dist/infrastructure/orchestration/thread-key-store.js +0 -127
- package/dist/infrastructure/orchestration/write-pass-store.js +0 -46
- package/dist/infrastructure/protocols/cloud-sync.js +0 -207
- package/dist/infrastructure/protocols/mcp-helpers.js +0 -25
- package/dist/infrastructure/protocols/mcp-server-impl.js +0 -2853
- package/dist/infrastructure/protocols/probe-port.js +0 -36
- package/dist/infrastructure/protocols/thread-phase.js +0 -105
- package/dist/infrastructure/protocols/ui-page-v2.js +0 -4418
- package/dist/infrastructure/protocols/ui-page.js +0 -2377
- package/dist/infrastructure/protocols/verify-page.js +0 -983
- package/dist/infrastructure/security/file-collection.js +0 -118
- package/dist/infrastructure/security/input-validator.js +0 -152
- package/dist/infrastructure/security/permissions-config.js +0 -234
- package/dist/infrastructure/security/trust-scorer.js +0 -657
- package/dist/infrastructure/storage/cross-tool-agents.js +0 -268
- package/dist/infrastructure/storage/embeddings-path.js +0 -37
- package/dist/infrastructure/storage/project-thread-migration.js +0 -237
- package/dist/infrastructure/storage/project-thread-mirror.js +0 -524
- package/dist/infrastructure/storage/project-thread-reader.js +0 -172
- package/dist/infrastructure/storage/project-thread-title-backfill.js +0 -214
- package/dist/infrastructure/storage/task-repository.js +0 -206
- package/dist/monitoring.js +0 -212
- package/dist/presentation/cli/commands/audit-command.js +0 -126
- package/dist/presentation/cli/commands/budget-command.js +0 -79
- package/dist/presentation/cli/commands/config-command.js +0 -125
- package/dist/presentation/cli/commands/context-source-command.js +0 -198
- package/dist/presentation/cli/commands/hook-command.js +0 -265
- package/dist/presentation/cli/commands/init-command.js +0 -578
- package/dist/presentation/cli/commands/memory-command.js +0 -1031
- package/dist/presentation/cli/commands/narrator-command.js +0 -101
- package/dist/presentation/cli/commands/permission-command.js +0 -116
- package/dist/presentation/cli/commands/protocols-builder.js +0 -254
- package/dist/presentation/cli/commands/protocols-command.js +0 -84
- package/dist/presentation/cli/commands/repo-map-builder.js +0 -247
- package/dist/presentation/cli/commands/report-command.js +0 -387
- package/dist/presentation/cli/commands/scan-tool-command.js +0 -94
- package/dist/presentation/cli/commands/setup-command.js +0 -307
- package/dist/presentation/cli/commands/status-command.js +0 -661
- package/dist/presentation/cli/commands/thread-command.js +0 -288
- package/dist/presentation/cli/commands/trust-command.js +0 -306
- package/dist/presentation/cli/commands/verify-command.js +0 -233
- package/dist/presentation/cli/error-display.js +0 -336
- package/dist/presentation/cli/repl.js +0 -797
- package/dist/presentation/cli/task-deliverable.js +0 -127
- package/dist/testing/cassette.js +0 -125
- package/dist/testing/replay-adapter.js +0 -166
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI Command: hook
|
|
3
|
-
*
|
|
4
|
-
* Manages Claude Code SDK hook integration.
|
|
5
|
-
* Intercepts every Claude Code tool call and runs Layer 0 security scan.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* codehere hook install # Add hooks to ~/.claude/settings.json
|
|
9
|
-
* codehere hook uninstall # Remove hooks
|
|
10
|
-
* codehere hook status # Show current hook config and recent events
|
|
11
|
-
* codehere hook log # Show recent audit log
|
|
12
|
-
* codehere hook log --tail 50 # Last 50 events
|
|
13
|
-
*/
|
|
14
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, copyFileSync, unlinkSync, rmdirSync, } from 'fs';
|
|
15
|
-
import { join, dirname } from 'path';
|
|
16
|
-
import { homedir } from 'os';
|
|
17
|
-
import { fileURLToPath } from 'url';
|
|
18
|
-
import { generateHookConfig, AUDIT_FILE } from '../../../infrastructure/hooks/claude-sdk-hook.js';
|
|
19
|
-
import { colors, success, error, warning, info, newline, sectionHeader } from '../../../ui.js';
|
|
20
|
-
// ── Skills management ─────────────────────────────────────────────────────────
|
|
21
|
-
const SKILLS_TARGET_DIR = join(homedir(), '.claude', 'commands', 'codehere');
|
|
22
|
-
function getSkillsSourceDir() {
|
|
23
|
-
// When running from dist/, the .claude/commands dir is at package root
|
|
24
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
-
const __dirname = dirname(__filename);
|
|
26
|
-
// dist/presentation/cli/commands → ../../../../.claude/commands
|
|
27
|
-
return join(__dirname, '..', '..', '..', '..', '.claude', 'commands');
|
|
28
|
-
}
|
|
29
|
-
function installSkills() {
|
|
30
|
-
const sourceDir = getSkillsSourceDir();
|
|
31
|
-
if (!existsSync(sourceDir))
|
|
32
|
-
return false;
|
|
33
|
-
if (!existsSync(SKILLS_TARGET_DIR)) {
|
|
34
|
-
mkdirSync(SKILLS_TARGET_DIR, { recursive: true });
|
|
35
|
-
}
|
|
36
|
-
const files = readdirSync(sourceDir).filter((f) => f.endsWith('.md'));
|
|
37
|
-
for (const file of files) {
|
|
38
|
-
copyFileSync(join(sourceDir, file), join(SKILLS_TARGET_DIR, file));
|
|
39
|
-
}
|
|
40
|
-
return files.length > 0;
|
|
41
|
-
}
|
|
42
|
-
function uninstallSkills() {
|
|
43
|
-
if (!existsSync(SKILLS_TARGET_DIR))
|
|
44
|
-
return;
|
|
45
|
-
try {
|
|
46
|
-
for (const file of readdirSync(SKILLS_TARGET_DIR)) {
|
|
47
|
-
unlinkSync(join(SKILLS_TARGET_DIR, file));
|
|
48
|
-
}
|
|
49
|
-
rmdirSync(SKILLS_TARGET_DIR);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
/* ignore */
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function skillsInstalled() {
|
|
56
|
-
return existsSync(SKILLS_TARGET_DIR) && readdirSync(SKILLS_TARGET_DIR).some((f) => f.endsWith('.md'));
|
|
57
|
-
}
|
|
58
|
-
const SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
|
|
59
|
-
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
60
|
-
function readSettings() {
|
|
61
|
-
if (!existsSync(SETTINGS_PATH))
|
|
62
|
-
return {};
|
|
63
|
-
try {
|
|
64
|
-
return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
return {};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function writeSettings(settings) {
|
|
71
|
-
const dir = join(homedir(), '.claude');
|
|
72
|
-
if (!existsSync(dir))
|
|
73
|
-
mkdirSync(dir, { recursive: true });
|
|
74
|
-
writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
|
|
75
|
-
}
|
|
76
|
-
function isInstalled(settings) {
|
|
77
|
-
const hooks = (settings.hooks ?? {});
|
|
78
|
-
const preToolUse = (hooks.PreToolUse ?? []);
|
|
79
|
-
return preToolUse.some((entry) => entry.hooks?.some((h) => h.command?.includes('codehere scan-tool')));
|
|
80
|
-
}
|
|
81
|
-
// ── command ───────────────────────────────────────────────────────────────────
|
|
82
|
-
export async function executeHookCommand(subcommand, options = {}) {
|
|
83
|
-
const sub = subcommand ?? 'status';
|
|
84
|
-
switch (sub) {
|
|
85
|
-
case 'install': {
|
|
86
|
-
const settings = readSettings();
|
|
87
|
-
if (isInstalled(settings)) {
|
|
88
|
-
console.log(warning('codehere hooks already installed'));
|
|
89
|
-
console.log(colors.dim(` Config: ${SETTINGS_PATH}`));
|
|
90
|
-
console.log(colors.dim(' Run `codehere hook status` to see details'));
|
|
91
|
-
newline();
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
const hookConfig = generateHookConfig({
|
|
95
|
-
logOnly: options.logOnly,
|
|
96
|
-
blockMode: options.blockMode,
|
|
97
|
-
});
|
|
98
|
-
// Merge with existing hooks config
|
|
99
|
-
const existingHooks = settings.hooks ?? {};
|
|
100
|
-
const mergedHooks = { ...existingHooks };
|
|
101
|
-
for (const [eventName, handlers] of Object.entries(hookConfig)) {
|
|
102
|
-
const existing = mergedHooks[eventName] ?? [];
|
|
103
|
-
mergedHooks[eventName] = [...existing, ...handlers];
|
|
104
|
-
}
|
|
105
|
-
settings.hooks = mergedHooks;
|
|
106
|
-
writeSettings(settings);
|
|
107
|
-
const skillsOk = installSkills();
|
|
108
|
-
console.log(success('codehere hooks installed'));
|
|
109
|
-
newline();
|
|
110
|
-
console.log(colors.bold('What happens now:'));
|
|
111
|
-
console.log(' Every Bash, Edit, Write, and MultiEdit call your AI makes is');
|
|
112
|
-
console.log(' scanned by codehere before it executes.');
|
|
113
|
-
console.log(' Zero API calls. < 5ms per scan. Runs entirely on your machine.');
|
|
114
|
-
newline();
|
|
115
|
-
console.log(colors.bold('Scan covers:'));
|
|
116
|
-
console.log(' • Prompt injection & jailbreak attempts');
|
|
117
|
-
console.log(' • Credential theft (API keys, SSH keys, env vars)');
|
|
118
|
-
console.log(' • Destructive operations (rm -rf, DB drops, force push)');
|
|
119
|
-
console.log(' • Code injection (curl|bash, reverse shells)');
|
|
120
|
-
console.log(' • Supply chain attacks (typosquatting packages)');
|
|
121
|
-
console.log(' • OWASP Top 10 patterns (SQLi, XSS, hardcoded secrets)');
|
|
122
|
-
newline();
|
|
123
|
-
console.log(colors.bold('Audit log:'));
|
|
124
|
-
console.log(colors.dim(` ${AUDIT_FILE}`));
|
|
125
|
-
newline();
|
|
126
|
-
if (options.logOnly) {
|
|
127
|
-
console.log(warning('Mode: log-only (no blocking). Run without --log-only to enable blocking.'));
|
|
128
|
-
newline();
|
|
129
|
-
}
|
|
130
|
-
console.log(colors.dim(' Config written to: ' + SETTINGS_PATH));
|
|
131
|
-
if (skillsOk) {
|
|
132
|
-
console.log(colors.dim(` Skills installed to: ${SKILLS_TARGET_DIR}`));
|
|
133
|
-
newline();
|
|
134
|
-
console.log(colors.bold('Slash commands now available in your AI assistant:'));
|
|
135
|
-
console.log(colors.dim(' /codehere:trust — scan current project'));
|
|
136
|
-
console.log(colors.dim(' /codehere:report — generate shareable audit report'));
|
|
137
|
-
console.log(colors.dim(' /codehere:audit — pre-merge security check'));
|
|
138
|
-
console.log(colors.dim(' /codehere:hook-status — check hook health'));
|
|
139
|
-
}
|
|
140
|
-
newline();
|
|
141
|
-
console.log(colors.dim(' Restart your AI assistant for changes to take effect.'));
|
|
142
|
-
newline();
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
case 'uninstall': {
|
|
146
|
-
const settings = readSettings();
|
|
147
|
-
if (!isInstalled(settings)) {
|
|
148
|
-
console.log(info('codehere hooks are not installed'));
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const hooks = settings.hooks;
|
|
152
|
-
for (const [eventName, handlers] of Object.entries(hooks)) {
|
|
153
|
-
if (Array.isArray(handlers)) {
|
|
154
|
-
hooks[eventName] = handlers.filter((entry) => !entry.hooks?.some((h) => h.command?.includes('codehere scan-tool')));
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
writeSettings(settings);
|
|
158
|
-
uninstallSkills();
|
|
159
|
-
console.log(success('codehere hooks and skills removed'));
|
|
160
|
-
console.log(colors.dim('Restart your AI assistant for changes to take effect.'));
|
|
161
|
-
newline();
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
case 'status': {
|
|
165
|
-
const settings = readSettings();
|
|
166
|
-
const installed = isInstalled(settings);
|
|
167
|
-
sectionHeader('codehere Hook Status');
|
|
168
|
-
newline();
|
|
169
|
-
if (installed) {
|
|
170
|
-
console.log(success('Running') + ' Intercepting every tool call before it executes.');
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
console.log(warning('Not installed') + ' Run `codehere hook install` to activate.');
|
|
174
|
-
}
|
|
175
|
-
newline();
|
|
176
|
-
const skills = skillsInstalled();
|
|
177
|
-
if (skills) {
|
|
178
|
-
console.log(info('Skills') + ' /codehere:trust /codehere:report /codehere:audit /codehere:hook-status');
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
console.log(colors.dim('Skills: not installed (run `codehere hook install` to add)'));
|
|
182
|
-
}
|
|
183
|
-
newline();
|
|
184
|
-
console.log(colors.dim('Config: ') + SETTINGS_PATH);
|
|
185
|
-
console.log(colors.dim('Audit log:') + ' ' + AUDIT_FILE);
|
|
186
|
-
newline();
|
|
187
|
-
// Autonomous mode callout
|
|
188
|
-
console.log(colors.bold('Autonomous mode (shift+tab)'));
|
|
189
|
-
console.log(colors.dim(' When Claude Code runs without approval prompts, this hook is your'));
|
|
190
|
-
console.log(colors.dim(' last line of defense. Every tool call is scanned before it executes.'));
|
|
191
|
-
console.log(colors.dim(' After a session: `codehere status --sessions` to review what happened.'));
|
|
192
|
-
newline();
|
|
193
|
-
// Show recent audit stats
|
|
194
|
-
if (existsSync(AUDIT_FILE)) {
|
|
195
|
-
const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-1000); // last 1000 events
|
|
196
|
-
if (lines.length > 0) {
|
|
197
|
-
const entries = lines
|
|
198
|
-
.map((l) => {
|
|
199
|
-
try {
|
|
200
|
-
return JSON.parse(l);
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
})
|
|
206
|
-
.filter(Boolean);
|
|
207
|
-
const total = entries.length;
|
|
208
|
-
const blocked = entries.filter((e) => e.blocked).length;
|
|
209
|
-
const critical = entries.filter((e) => (e.criticalFindings ?? 0) > 0).length;
|
|
210
|
-
console.log(colors.bold("What it's seen") + colors.dim(' (last 1000 events):'));
|
|
211
|
-
console.log(` ${colors.cyan(String(total))} tool calls scanned`);
|
|
212
|
-
console.log(` ${blocked > 0 ? colors.red(String(blocked)) : colors.green('none')} blocked`);
|
|
213
|
-
console.log(` ${critical > 0 ? colors.red(String(critical)) : colors.green('none')} with critical findings`);
|
|
214
|
-
newline();
|
|
215
|
-
if (blocked > 0) {
|
|
216
|
-
console.log(colors.dim(' Run `codehere status --sessions` to see which sessions had blocks.'));
|
|
217
|
-
newline();
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
console.log(colors.dim(" No events logged yet — run Claude Code and it'll start tracking."));
|
|
223
|
-
newline();
|
|
224
|
-
}
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
case 'log': {
|
|
228
|
-
const tail = options.tail ?? 20;
|
|
229
|
-
if (!existsSync(AUDIT_FILE)) {
|
|
230
|
-
console.log(info('No audit log yet'));
|
|
231
|
-
console.log(colors.dim(' Run `codehere hook install` first'));
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-tail);
|
|
235
|
-
if (lines.length === 0) {
|
|
236
|
-
console.log(info('Audit log is empty'));
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
sectionHeader(`Hook Audit Log (last ${lines.length})`);
|
|
240
|
-
newline();
|
|
241
|
-
for (const line of lines) {
|
|
242
|
-
try {
|
|
243
|
-
const entry = JSON.parse(line);
|
|
244
|
-
const ts = new Date(entry.timestamp).toLocaleTimeString();
|
|
245
|
-
const status = entry.blocked ? colors.red('[BLOCKED]') : colors.green('[ALLOW] ');
|
|
246
|
-
const risk = entry.riskScore > 0 ? colors.yellow(` risk:${entry.riskScore}`) : '';
|
|
247
|
-
const tool = colors.cyan(entry.toolName.padEnd(10));
|
|
248
|
-
const preview = entry.toolInput.substring(0, 60).replace(/\n/g, ' ');
|
|
249
|
-
console.log(` ${ts} ${status} ${tool}${risk} ${colors.dim(preview)}`);
|
|
250
|
-
}
|
|
251
|
-
catch {
|
|
252
|
-
// skip malformed line
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
newline();
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
default: {
|
|
259
|
-
console.log(error(`Unknown subcommand: ${sub}`));
|
|
260
|
-
console.log(colors.dim('Usage: codehere hook install|uninstall|status|log'));
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
//# sourceMappingURL=hook-command.js.map
|