@neurosec/sentry 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/bin/cli.js +18 -0
  4. package/bin/sentryd.js +19 -0
  5. package/dist/api.d.ts +21 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +161 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/audit.d.ts +18 -0
  10. package/dist/audit.d.ts.map +1 -0
  11. package/dist/audit.js +114 -0
  12. package/dist/audit.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +255 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/config.d.ts +54 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +160 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/discovery.d.ts +5 -0
  22. package/dist/discovery.d.ts.map +1 -0
  23. package/dist/discovery.js +279 -0
  24. package/dist/discovery.js.map +1 -0
  25. package/dist/enforcement/enforcement-engine.d.ts +37 -0
  26. package/dist/enforcement/enforcement-engine.d.ts.map +1 -0
  27. package/dist/enforcement/enforcement-engine.js +325 -0
  28. package/dist/enforcement/enforcement-engine.js.map +1 -0
  29. package/dist/enforcement/file-monitor.d.ts +4 -0
  30. package/dist/enforcement/file-monitor.d.ts.map +1 -0
  31. package/dist/enforcement/file-monitor.js +114 -0
  32. package/dist/enforcement/file-monitor.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +248 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/logger.d.ts +2 -0
  38. package/dist/logger.d.ts.map +1 -0
  39. package/dist/logger.js +17 -0
  40. package/dist/logger.js.map +1 -0
  41. package/dist/sandbox/index.d.ts +14 -0
  42. package/dist/sandbox/index.d.ts.map +1 -0
  43. package/dist/sandbox/index.js +91 -0
  44. package/dist/sandbox/index.js.map +1 -0
  45. package/dist/sandbox/linux-sandbox.d.ts +21 -0
  46. package/dist/sandbox/linux-sandbox.d.ts.map +1 -0
  47. package/dist/sandbox/linux-sandbox.js +186 -0
  48. package/dist/sandbox/linux-sandbox.js.map +1 -0
  49. package/dist/sandbox/macos-sandbox.d.ts +17 -0
  50. package/dist/sandbox/macos-sandbox.d.ts.map +1 -0
  51. package/dist/sandbox/macos-sandbox.js +145 -0
  52. package/dist/sandbox/macos-sandbox.js.map +1 -0
  53. package/dist/setup.d.ts +14 -0
  54. package/dist/setup.d.ts.map +1 -0
  55. package/dist/setup.js +220 -0
  56. package/dist/setup.js.map +1 -0
  57. package/dist/skill-authz/skill-evaluator.d.ts +20 -0
  58. package/dist/skill-authz/skill-evaluator.d.ts.map +1 -0
  59. package/dist/skill-authz/skill-evaluator.js +159 -0
  60. package/dist/skill-authz/skill-evaluator.js.map +1 -0
  61. package/dist/skill-authz/skill-scanner.d.ts +18 -0
  62. package/dist/skill-authz/skill-scanner.d.ts.map +1 -0
  63. package/dist/skill-authz/skill-scanner.js +169 -0
  64. package/dist/skill-authz/skill-scanner.js.map +1 -0
  65. package/dist/telemetry.d.ts +18 -0
  66. package/dist/telemetry.d.ts.map +1 -0
  67. package/dist/telemetry.js +106 -0
  68. package/dist/telemetry.js.map +1 -0
  69. package/dist/types.d.ts +127 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +209 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +69 -0
  74. package/scripts/install-sentry-macos.sh +238 -0
  75. package/scripts/install-sentry.sh +253 -0
  76. package/scripts/postinstall.js +191 -0
  77. package/scripts/prepack.js +33 -0
@@ -0,0 +1,253 @@
1
+ #!/usr/bin/env bash
2
+ # NeuroShield Sentry Daemon — Linux systemd Installation Script
3
+ # Usage: sudo bash install-sentry.sh [--mode enforce|monitor|quarantine]
4
+
5
+ set -euo pipefail
6
+
7
+ SENTRY_VERSION="${SENTRY_VERSION:-1.0.0}"
8
+ INSTALL_DIR="/usr/local/lib/neuroshield"
9
+ CONFIG_DIR="/etc/neuroshield"
10
+ STATE_DIR="/var/lib/neuroshield/sentry"
11
+ LOG_DIR="/var/log/neuroshield"
12
+ BIN_PATH="/usr/local/bin/neuroshield-sentryd"
13
+ CONFIG_PATH="${CONFIG_DIR}/sentry.yaml"
14
+ SERVICE_NAME="neuroshield-sentry"
15
+ SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
16
+ ENFORCEMENT_MODE="${1:-monitor}"
17
+ MODE_FLAG="${1:-}"
18
+ if [ -z "${MODE_FLAG}" ]; then
19
+ MODE_FLAG="monitor"
20
+ fi
21
+
22
+ # Parse --mode flag
23
+ if [[ "${MODE_FLAG}" == --mode=* ]]; then
24
+ ENFORCEMENT_MODE="${MODE_FLAG#*=}"
25
+ elif [[ "${MODE_FLAG}" == --mode ]]; then
26
+ ENFORCEMENT_MODE="$2"
27
+ fi
28
+
29
+ echo "============================================"
30
+ echo " NeuroShield Sentry v${SENTRY_VERSION} Installer"
31
+ echo " Mode: ${ENFORCEMENT_MODE}"
32
+ echo "============================================"
33
+
34
+ # Check prerequisites
35
+ if [ "$EUID" -ne 0 ]; then
36
+ echo "Error: This script must be run as root (sudo)" >&2
37
+ exit 1
38
+ fi
39
+
40
+ if ! command -v node &>/dev/null; then
41
+ echo "Error: Node.js is required (>= 20)" >&2
42
+ exit 1
43
+ fi
44
+
45
+ NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
46
+ if [ "${NODE_VERSION}" -lt 20 ]; then
47
+ echo "Error: Node.js >= 20 required (found v${NODE_VERSION})" >&2
48
+ exit 1
49
+ fi
50
+
51
+ # Create directories
52
+ echo "Creating directories..."
53
+ mkdir -p "${INSTALL_DIR}"
54
+ mkdir -p "${CONFIG_DIR}"
55
+ mkdir -p "${STATE_DIR}"
56
+ mkdir -p "${LOG_DIR}"
57
+
58
+ # Build the sentry package
59
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
60
+ PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
61
+ SENTRY_PACKAGE="${PROJECT_DIR}/packages/sentry"
62
+
63
+ if [ -f "${SENTRY_PACKAGE}/package.json" ]; then
64
+ echo "Building sentry daemon from source..."
65
+ cd "${SENTRY_PACKAGE}"
66
+ if [ ! -d "node_modules" ]; then
67
+ npm install --production
68
+ fi
69
+ npx tsc --outDir dist 2>/dev/null || true
70
+ cp -r dist "${INSTALL_DIR}/"
71
+ cp -r node_modules "${INSTALL_DIR}/"
72
+ cp package.json "${INSTALL_DIR}/"
73
+ else
74
+ echo "Warning: Sentry package not found at ${SENTRY_PACKAGE}"
75
+ echo "Creating placeholder..."
76
+ mkdir -p "${INSTALL_DIR}/dist"
77
+ cat > "${INSTALL_DIR}/package.json" <<- EOF
78
+ {
79
+ "name": "@neurosec/sentry",
80
+ "version": "${SENTRY_VERSION}"
81
+ }
82
+ EOF
83
+ fi
84
+
85
+ # Install binary wrapper
86
+ cat > "${BIN_PATH}" <<- 'BINEOF'
87
+ #!/usr/bin/env node
88
+ require('/usr/local/lib/neuroshield/dist/index.js');
89
+ BINEOF
90
+ chmod +x "${BIN_PATH}"
91
+
92
+ # Generate default config if not exists
93
+ if [ ! -f "${CONFIG_PATH}" ]; then
94
+ echo "Generating default config..."
95
+ cat > "${CONFIG_PATH}" <<- EOF
96
+ # NeuroShield Sentry Daemon Configuration
97
+ sentry:
98
+ host_id: "$(hostname)-sentry"
99
+ version: "${SENTRY_VERSION}"
100
+ health_port: 9190
101
+ api_port: 9191
102
+ state_dir: ${STATE_DIR}
103
+ pid_file_path: /var/run/neuroshield-sentry.pid
104
+
105
+ neurosec:
106
+ endpoint: "https://api.neurosec.ai"
107
+ org_id: "${NEUROSEC_ORG_ID:-}"
108
+ token_path: ${CONFIG_DIR}/sentry.token
109
+ tls_cert: ${CONFIG_DIR}/cert.pem
110
+ tls_key: ${CONFIG_DIR}/key.pem
111
+ sync_interval_ms: 30000
112
+ heartbeat_interval_ms: 300000
113
+
114
+ enforcement:
115
+ mode: "${ENFORCEMENT_MODE}"
116
+ sandbox_enabled: true
117
+ syscall_filter_enabled: true
118
+ network_filter_enabled: true
119
+ filesystem_filter_enabled: true
120
+
121
+ sandbox_defaults:
122
+ cpu_max: "0.5"
123
+ memory_max: "512MB"
124
+ pid_max: 100
125
+
126
+ network:
127
+ allow_hosts:
128
+ - "api.openai.com:443"
129
+ - "api.anthropic.com:443"
130
+ - "api.neurosec.ai:443"
131
+ block_hosts:
132
+ - "*.pastebin.com"
133
+ - "*.ngrok.io"
134
+ - "*.requestbin.net"
135
+ - "*.webhook.site"
136
+ allow_private: false
137
+ dns_monitor_enabled: true
138
+
139
+ skill_authz:
140
+ enabled: true
141
+ allow_unknown: false
142
+ require_approval:
143
+ - "shell_exec"
144
+ - "bash"
145
+ - "terminal"
146
+ - "run_command"
147
+ - "execute_command"
148
+
149
+ audit:
150
+ log_path: ${LOG_DIR}/sentry.log
151
+ retention_days: 90
152
+ max_size_mb: 500
153
+
154
+ discovery:
155
+ interval_ms: 30000
156
+ source_paths:
157
+ - /workspace
158
+ - /app
159
+ - /home
160
+ - /tmp
161
+ EOF
162
+ echo " Config written to ${CONFIG_PATH}"
163
+ echo " IMPORTANT: Edit ${CONFIG_PATH} and set:"
164
+ echo " - neurosec.org_id"
165
+ echo " - Place token at ${CONFIG_DIR}/sentry.token"
166
+ echo " - Place TLS cert at ${CONFIG_DIR}/cert.pem"
167
+ echo " - Place TLS key at ${CONFIG_DIR}/key.pem"
168
+ fi
169
+
170
+ # Create empty token file with secure permissions if it doesn't exist
171
+ if [ ! -f "${CONFIG_DIR}/sentry.token" ]; then
172
+ touch "${CONFIG_DIR}/sentry.token"
173
+ chmod 600 "${CONFIG_DIR}/sentry.token"
174
+ echo " Created empty token file: ${CONFIG_DIR}/sentry.token"
175
+ fi
176
+
177
+ # Install systemd service
178
+ echo "Installing systemd service..."
179
+ cat > "${SERVICE_FILE}" <<- EOF
180
+ [Unit]
181
+ Description=NeuroShield Sentry — Host-Level Agent Protection Daemon
182
+ Documentation=https://docs.neurosec.ai/sentry
183
+ After=network.target network-online.target
184
+ Wants=network-online.target
185
+
186
+ [Service]
187
+ Type=simple
188
+ ExecStart=${BIN_PATH} ${CONFIG_PATH}
189
+ Restart=always
190
+ RestartSec=10
191
+ TimeoutStopSec=30
192
+ KillMode=process
193
+ SendSIGKILL=no
194
+
195
+ # Security hardening
196
+ NoNewPrivileges=yes
197
+ PrivateTmp=yes
198
+ ProtectHome=read-only
199
+ ProtectSystem=strict
200
+ ReadWritePaths=${STATE_DIR} ${LOG_DIR} ${CONFIG_DIR}
201
+ ReadOnlyPaths=/usr/local/lib/neuroshield
202
+
203
+ # Capabilities for sandboxing (cgroups, seccomp, network filtering)
204
+ CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_ADMIN CAP_NET_RAW CAP_KILL
205
+ AmbientCapabilities=CAP_SYS_ADMIN CAP_NET_ADMIN CAP_NET_RAW CAP_KILL
206
+
207
+ # Resource limits
208
+ MemoryMax=512M
209
+ CPUQuota=50%
210
+ LimitNOFILE=65536
211
+
212
+ # Environment
213
+ Environment=NODE_ENV=production
214
+ Environment=SENTRY_CONFIG_PATH=${CONFIG_PATH}
215
+ Environment=LOG_LEVEL=info
216
+
217
+ # Logging
218
+ StandardOutput=journal
219
+ StandardError=journal
220
+
221
+ [Install]
222
+ WantedBy=multi-user.target
223
+ EOF
224
+
225
+ chmod 644 "${SERVICE_FILE}"
226
+ echo " Service file: ${SERVICE_FILE}"
227
+
228
+ # Enable and start service
229
+ systemctl daemon-reload
230
+ systemctl enable "${SERVICE_NAME}"
231
+
232
+ echo ""
233
+ echo "============================================"
234
+ echo " Installation Complete!"
235
+ echo "============================================"
236
+ echo ""
237
+ echo " Next steps:"
238
+ echo " 1. Edit ${CONFIG_PATH} with your NeuroSec org ID"
239
+ echo " 2. Set your sentry token: echo 'your-token' > ${CONFIG_DIR}/sentry.token"
240
+ echo " 3. Start the daemon: systemctl start ${SERVICE_NAME}"
241
+ echo " 4. Check status: systemctl status ${SERVICE_NAME}"
242
+ echo " 5. View logs: journalctl -u ${SERVICE_NAME} -f"
243
+ echo " 6. Local API: curl http://127.0.0.1:9191/api/v1/status"
244
+ echo ""
245
+ echo " Monitoring mode: ${ENFORCEMENT_MODE}"
246
+ echo " - monitor: Log violations only (safe for initial rollout)"
247
+ echo " - enforce: Block violations per policy"
248
+ echo " - quarantine: Block everything, kill on repeated violations"
249
+ echo ""
250
+ echo " To switch mode later:"
251
+ echo " sed -i 's/mode:.*/mode: \"enforce\"/' ${CONFIG_PATH}"
252
+ echo " systemctl restart ${SERVICE_NAME}"
253
+ echo ""
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NeuroShield Sentry — postinstall script
4
+ * Runs after `npm install @neurosec/sentry` or `npm install -g @neurosec/sentry`
5
+ *
6
+ * Creates a default sentry.yaml in /etc/neuroshield/ (or user-local fallback)
7
+ * so the daemon works out of the box. The user should run `neuroshield-sentry setup`
8
+ * for a guided configuration.
9
+ */
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const os = require('os');
13
+ const crypto = require('crypto');
14
+
15
+ const VERSION = '1.0.0';
16
+
17
+ function getPlatformPaths() {
18
+ const platform = os.platform();
19
+ if (platform === 'darwin') {
20
+ return {
21
+ configDir: '/usr/local/etc/neuroshield',
22
+ configPath: '/usr/local/etc/neuroshield/sentry.yaml',
23
+ tokenPath: '/usr/local/etc/neuroshield/sentry.token',
24
+ stateDir: '/usr/local/var/lib/neuroshield/sentry',
25
+ logDir: '/usr/local/var/log/neuroshield',
26
+ pidFile: '/usr/local/var/run/neuroshield-sentry.pid',
27
+ };
28
+ }
29
+ if (platform === 'linux') {
30
+ return {
31
+ configDir: '/etc/neuroshield',
32
+ configPath: '/etc/neuroshield/sentry.yaml',
33
+ tokenPath: '/etc/neuroshield/sentry.token',
34
+ stateDir: '/var/lib/neuroshield/sentry',
35
+ logDir: '/var/log/neuroshield',
36
+ pidFile: '/var/run/neuroshield-sentry.pid',
37
+ };
38
+ }
39
+ // fallback: user-local
40
+ const home = os.homedir();
41
+ return {
42
+ configDir: path.join(home, '.config', 'neuroshield'),
43
+ configPath: path.join(home, '.config', 'neuroshield', 'sentry.yaml'),
44
+ tokenPath: path.join(home, '.config', 'neuroshield', 'sentry.token'),
45
+ stateDir: path.join(home, '.local', 'share', 'neuroshield', 'sentry'),
46
+ logDir: path.join(home, '.local', 'share', 'neuroshield', 'logs'),
47
+ pidFile: path.join(home, '.local', 'run', 'neuroshield-sentry.pid'),
48
+ };
49
+ }
50
+
51
+ function generateDefaultConfig(paths) {
52
+ const hostname = os.hostname();
53
+ const token = `nst_${crypto.randomBytes(24).toString('hex')}`;
54
+
55
+ return `# NeuroShield Sentry Daemon Configuration
56
+ # Auto-generated by postinstall at ${new Date().toISOString()}
57
+ # Run \`neuroshield-sentry setup\` for an interactive guided setup
58
+
59
+ sentry:
60
+ host_id: "${hostname}-sentry"
61
+ version: "${VERSION}"
62
+ health_port: 9190
63
+ api_port: 9191
64
+ state_dir: "${paths.stateDir}"
65
+ pid_file_path: "${paths.pidFile}"
66
+
67
+ neurosec:
68
+ endpoint: "https://api.neurosec.ai"
69
+ org_id: ""
70
+ token_path: "${paths.tokenPath}"
71
+ sync_interval_ms: 30000
72
+ heartbeat_interval_ms: 300000
73
+
74
+ enforcement:
75
+ mode: "monitor"
76
+ sandbox_enabled: ${os.platform() === 'linux' ? 'true' : 'false'}
77
+ syscall_filter_enabled: ${os.platform() === 'linux' ? 'true' : 'false'}
78
+ network_filter_enabled: true
79
+ filesystem_filter_enabled: true
80
+
81
+ sandbox_defaults:
82
+ cpu_max: "0.5"
83
+ memory_max: "512MB"
84
+ pid_max: 100
85
+
86
+ network:
87
+ allow_hosts:
88
+ - "api.openai.com:443"
89
+ - "api.anthropic.com:443"
90
+ - "api.neurosec.ai:443"
91
+ block_hosts:
92
+ - "*.pastebin.com"
93
+ - "*.ngrok.io"
94
+ - "*.requestbin.net"
95
+ - "*.webhook.site"
96
+ allow_private: false
97
+ dns_monitor_enabled: true
98
+
99
+ skill_authz:
100
+ enabled: true
101
+ allow_unknown: false
102
+ require_approval:
103
+ - "shell_exec"
104
+ - "bash"
105
+ - "terminal"
106
+ - "run_command"
107
+
108
+ audit:
109
+ log_path: "${paths.logDir}/sentry.log"
110
+ retention_days: 90
111
+ max_size_mb: 500
112
+
113
+ discovery:
114
+ interval_ms: 30000
115
+ source_paths:
116
+ - /workspace
117
+ - /app
118
+ - /home
119
+ - /tmp
120
+ `;
121
+ }
122
+
123
+ function main() {
124
+ const paths = getPlatformPaths();
125
+ const configDir = paths.configDir;
126
+ const configPath = paths.configPath;
127
+ const tokenPath = paths.tokenPath;
128
+
129
+ // Skip if config already exists
130
+ if (fs.existsSync(configPath)) {
131
+ console.log(`[neuroshield-sentry] Config already exists at ${configPath} — skipping`);
132
+ return;
133
+ }
134
+
135
+ // Create directories
136
+ const dirs = [configDir, paths.stateDir, paths.logDir, path.dirname(paths.pidFile)];
137
+ for (const dir of dirs) {
138
+ try {
139
+ fs.mkdirSync(dir, { recursive: true });
140
+ } catch (e) {
141
+ console.warn(`[neuroshield-sentry] Warning: could not create ${dir}: ${e.message}`);
142
+ }
143
+ }
144
+
145
+ // Write default config
146
+ const content = generateDefaultConfig(paths);
147
+ try {
148
+ fs.writeFileSync(configPath, content, 'utf8');
149
+ console.log(`[neuroshield-sentry] Default config written to ${configPath}`);
150
+ } catch (e) {
151
+ console.warn(`[neuroshield-sentry] Warning: could not write config to ${configPath}`);
152
+ console.warn(` ${e.message}`);
153
+ console.warn(` Run \`sudo neuroshield-sentry setup\` to configure.`);
154
+ return;
155
+ }
156
+
157
+ // Write placeholder token
158
+ try {
159
+ const placeholderToken = `nst_${crypto.randomBytes(24).toString('hex')}`;
160
+ fs.writeFileSync(tokenPath, placeholderToken, 'utf8');
161
+ fs.chmodSync(tokenPath, 0o600);
162
+ console.log(`[neuroshield-sentry] Token file created at ${tokenPath}`);
163
+ } catch (e) {
164
+ console.warn(`[neuroshield-sentry] Warning: could not write token: ${e.message}`);
165
+ }
166
+
167
+ console.log('');
168
+ console.log('╔══════════════════════════════════════════════════════════╗');
169
+ console.log('║ NeuroShield Sentry installed! ║');
170
+ console.log('╠══════════════════════════════════════════════════════════╣');
171
+ console.log('║ ║');
172
+ console.log('║ Next steps: ║');
173
+ console.log('║ ║');
174
+ console.log('║ 1. Configure your NeuroSec connection: ║');
175
+ console.log(`║ neuroshield-sentry setup ║`);
176
+ console.log('║ (or set env vars: NEUROSEC_ORG_ID, etc.) ║');
177
+ console.log('║ ║');
178
+ console.log('║ 2. Install as a system service: ║');
179
+ console.log('║ sudo neuroshield-sentry install ║');
180
+ console.log('║ ║');
181
+ console.log('║ 3. Or run directly: ║');
182
+ console.log('║ sudo neuroshield-sentryd ║');
183
+ console.log('║ ║');
184
+ console.log('║ 4. Check status: ║');
185
+ console.log('║ neuroshield-sentry status ║');
186
+ console.log('║ ║');
187
+ console.log('╚══════════════════════════════════════════════════════════╝');
188
+ console.log('');
189
+ }
190
+
191
+ main();
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NeuroShield Sentry — prepack script
4
+ * Runs before `npm pack` / `npm publish`.
5
+ * Ensures everything is built and ready for distribution.
6
+ */
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const REQUIRED_FILES = [
11
+ 'dist/index.js',
12
+ 'dist/cli.js',
13
+ 'dist/setup.js',
14
+ 'bin/sentryd.js',
15
+ 'bin/cli.js',
16
+ 'scripts/postinstall.js',
17
+ 'package.json',
18
+ ];
19
+
20
+ let allOk = true;
21
+ for (const file of REQUIRED_FILES) {
22
+ const fullPath = path.resolve(__dirname, '..', file);
23
+ if (!fs.existsSync(fullPath)) {
24
+ console.error(`[prepack] MISSING: ${file} — run \`npm run build\` first`);
25
+ allOk = false;
26
+ }
27
+ }
28
+
29
+ if (!allOk) {
30
+ process.exit(1);
31
+ }
32
+
33
+ console.log(`[prepack] All required files present. Package ready for publish.`);