infrawise 0.5.0 → 0.7.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.
@@ -1,28 +1,22 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.runAuth = runAuth;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const inquirer_1 = __importDefault(require("inquirer"));
9
- const ora_1 = __importDefault(require("ora"));
10
- const utils_1 = require("../utils");
11
- const dynamodb_1 = require("../../adapters/dynamodb");
12
- async function runAuth() {
13
- (0, utils_1.printHeader)('AWS Authentication');
14
- const profiles = (0, utils_1.readAWSProfiles)();
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import ora from 'ora';
4
+ import { readAWSProfiles, log, printHeader } from '../utils.js';
5
+ import { validateDynamoAccess } from '../../adapters/dynamodb.js';
6
+ export async function runAuth() {
7
+ printHeader('AWS Authentication');
8
+ const profiles = readAWSProfiles();
15
9
  if (profiles.length === 0) {
16
- utils_1.log.fail('No AWS profiles found');
10
+ log.fail('No AWS profiles found');
17
11
  console.log('');
18
- utils_1.log.info('Run ' + chalk_1.default.cyan('aws configure') + ' to set up credentials');
19
- utils_1.log.info('Or manually edit ' + chalk_1.default.dim('~/.aws/credentials'));
12
+ log.info('Run ' + chalk.cyan('aws configure') + ' to set up credentials');
13
+ log.info('Or manually edit ' + chalk.dim('~/.aws/credentials'));
20
14
  console.log('');
21
15
  return;
22
16
  }
23
- utils_1.log.success(`Found ${profiles.length} profile(s)`);
17
+ log.success(`Found ${profiles.length} profile(s)`);
24
18
  console.log('');
25
- const { selectedProfile } = await inquirer_1.default.prompt([
19
+ const { selectedProfile } = await inquirer.prompt([
26
20
  {
27
21
  type: 'list',
28
22
  name: 'selectedProfile',
@@ -31,27 +25,27 @@ async function runAuth() {
31
25
  },
32
26
  ]);
33
27
  console.log('');
34
- const spin = (0, ora_1.default)({ text: chalk_1.default.dim(`Validating "${selectedProfile}"...`), color: 'cyan' }).start();
28
+ const spin = ora({ text: chalk.dim(`Validating "${selectedProfile}"...`), color: 'cyan' }).start();
35
29
  const testConfig = {
36
30
  project: 'auth-test',
37
31
  aws: { profile: selectedProfile, region: 'us-east-1' },
38
32
  };
39
- const isValid = await (0, dynamodb_1.validateDynamoAccess)(testConfig);
33
+ const isValid = await validateDynamoAccess(testConfig);
40
34
  if (isValid) {
41
- spin.succeed(chalk_1.default.green(`Profile "${chalk_1.default.bold(selectedProfile)}" is valid`));
35
+ spin.succeed(chalk.green(`Profile "${chalk.bold(selectedProfile)}" is valid`));
42
36
  console.log('');
43
- console.log(chalk_1.default.dim(' Update your infrawise.yaml:'));
44
- console.log(chalk_1.default.cyan(` aws:\n profile: ${selectedProfile}`));
37
+ console.log(chalk.dim(' Update your infrawise.yaml:'));
38
+ console.log(chalk.cyan(` aws:\n profile: ${selectedProfile}`));
45
39
  }
46
40
  else {
47
- spin.fail(chalk_1.default.red(`Profile "${chalk_1.default.bold(selectedProfile)}" cannot access DynamoDB`));
41
+ spin.fail(chalk.red(`Profile "${chalk.bold(selectedProfile)}" cannot access DynamoDB`));
48
42
  console.log('');
49
- utils_1.log.warn('Possible causes:');
50
- utils_1.log.dim('Missing IAM permissions — need dynamodb:ListTables, dynamodb:DescribeTable');
51
- utils_1.log.dim('Expired SSO — run: aws sso login');
52
- utils_1.log.dim('Wrong region — check your AWS config');
43
+ log.warn('Possible causes:');
44
+ log.dim('Missing IAM permissions — need dynamodb:ListTables, dynamodb:DescribeTable');
45
+ log.dim('Expired SSO — run: aws sso login');
46
+ log.dim('Wrong region — check your AWS config');
53
47
  console.log('');
54
- utils_1.log.info(`Run ${chalk_1.default.cyan('infrawise doctor')} for a full diagnostic`);
48
+ log.info(`Run ${chalk.cyan('infrawise doctor')} for a full diagnostic`);
55
49
  }
56
50
  console.log('');
57
51
  }
@@ -1,50 +1,11 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.runDev = runDev;
40
- const fs = __importStar(require("fs"));
41
- const path = __importStar(require("path"));
42
- const chalk_1 = __importDefault(require("chalk"));
43
- const ora_1 = __importDefault(require("ora"));
44
- const core_1 = require("../../core");
45
- const server_1 = require("../../server");
46
- const utils_1 = require("../utils");
47
- const analyze_1 = require("./analyze");
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { loadConfig, formatError, readCache } from '../../core/index.js';
6
+ import { createServer, setGraphState } from '../../server/index.js';
7
+ import { log, printHeader } from '../utils.js';
8
+ import { runAnalyze, runCodeRefresh } from './analyze.js';
48
9
  const BOX_W = 52;
49
10
  const TOOL_MAP = [
50
11
  { name: 'get_infra_overview' },
@@ -59,6 +20,7 @@ const TOOL_MAP = [
59
20
  { name: 'get_secrets_overview', service: 'secretsManager' },
60
21
  { name: 'get_parameter_overview', service: 'ssm' },
61
22
  { name: 'get_lambda_overview', service: 'lambda' },
23
+ { name: 'get_eventbridge_details', service: 'eventbridge' },
62
24
  { name: 'get_log_errors', service: 'cloudwatchLogs' },
63
25
  ];
64
26
  function isEnabled(cfg, service) {
@@ -69,10 +31,10 @@ function isEnabled(cfg, service) {
69
31
  }
70
32
  function boxLine(visibleContent, coloredContent) {
71
33
  const padding = ' '.repeat(Math.max(0, BOX_W - visibleContent.length));
72
- console.log(chalk_1.default.dim(' │') + coloredContent + padding + chalk_1.default.dim('│'));
34
+ console.log(chalk.dim(' │') + coloredContent + padding + chalk.dim('│'));
73
35
  }
74
36
  function boxDivider() {
75
- console.log(chalk_1.default.dim(' ├────────────────────────────────────────────────────┤'));
37
+ console.log(chalk.dim(' ├────────────────────────────────────────────────────┤'));
76
38
  }
77
39
  function groupTools(tools) {
78
40
  const lines = [];
@@ -91,40 +53,40 @@ function groupTools(tools) {
91
53
  }
92
54
  return lines;
93
55
  }
94
- async function runDev(options = {}) {
56
+ export async function runDev(options = {}) {
95
57
  const port = options.port ?? 3000;
96
- (0, utils_1.printHeader)('MCP Server');
58
+ printHeader('MCP Server');
97
59
  let config;
98
60
  try {
99
- config = (0, core_1.loadConfig)(options.config);
100
- utils_1.log.success('Config loaded', options.config ?? 'infrawise.yaml');
61
+ config = loadConfig(options.config);
62
+ log.success('Config loaded', options.config ?? 'infrawise.yaml');
101
63
  }
102
64
  catch (err) {
103
- console.error((0, core_1.formatError)(err));
65
+ console.error(formatError(err));
104
66
  process.exit(1);
105
67
  }
106
68
  const repoPath = process.cwd();
107
69
  // Auto-analyze if no cache
108
- const cachedGraph = (0, core_1.readCache)('graph');
109
- const cachedFindings = (0, core_1.readCache)('findings');
70
+ const cachedGraph = readCache('graph');
71
+ const cachedFindings = readCache('findings');
110
72
  if (cachedGraph && cachedFindings) {
111
- utils_1.log.success('Cached analysis loaded', `${cachedGraph.nodes.length} nodes · ${cachedGraph.edges.length} edges · ${cachedFindings.length} finding(s)`);
112
- (0, server_1.setGraphState)(cachedGraph, cachedFindings);
73
+ log.success('Cached analysis loaded', `${cachedGraph.nodes.length} nodes · ${cachedGraph.edges.length} edges · ${cachedFindings.length} finding(s)`);
74
+ setGraphState(cachedGraph, cachedFindings, config);
113
75
  }
114
76
  else {
115
- utils_1.log.warn('No cache found — running analysis now...');
77
+ log.warn('No cache found — running analysis now...');
116
78
  console.log('');
117
- await (0, analyze_1.runAnalyze)({ repo: repoPath, config: options.config });
118
- const freshGraph = (0, core_1.readCache)('graph') ?? { nodes: [], edges: [] };
119
- const freshFindings = (0, core_1.readCache)('findings') ?? [];
120
- (0, server_1.setGraphState)(freshGraph, freshFindings);
79
+ await runAnalyze({ repo: repoPath, config: options.config });
80
+ const freshGraph = readCache('graph') ?? { nodes: [], edges: [] };
81
+ const freshFindings = readCache('findings') ?? [];
82
+ setGraphState(freshGraph, freshFindings, config);
121
83
  }
122
84
  console.log('');
123
85
  // Start server
124
- const spin = (0, ora_1.default)({ text: chalk_1.default.dim('Starting server...'), color: 'cyan' }).start();
125
- const { start } = (0, server_1.createServer)(port);
86
+ const spin = ora({ text: chalk.dim('Starting server...'), color: 'cyan' }).start();
87
+ const { start } = createServer(port);
126
88
  await start();
127
- spin.succeed(chalk_1.default.green('Server running'));
89
+ spin.succeed(chalk.green('Server running'));
128
90
  // Compute active/inactive tools from config
129
91
  const activeTools = TOOL_MAP.filter((t) => isEnabled(config, t.service)).map((t) => t.name);
130
92
  const inactiveTools = TOOL_MAP.filter((t) => !isEnabled(config, t.service)).map((t) => t.name);
@@ -133,30 +95,30 @@ async function runDev(options = {}) {
133
95
  const healthUrl = `http://localhost:${port}/health`;
134
96
  // Print box
135
97
  console.log('');
136
- console.log(chalk_1.default.dim(' ┌────────────────────────────────────────────────────┐'));
137
- boxLine(' MCP Server', chalk_1.default.bold(' MCP Server'));
98
+ console.log(chalk.dim(' ┌────────────────────────────────────────────────────┐'));
99
+ boxLine(' MCP Server', chalk.bold(' MCP Server'));
138
100
  boxDivider();
139
- boxLine(` POST ${mcpUrl}`, ` ${chalk_1.default.dim('POST')} ${chalk_1.default.cyan(mcpUrl)}`);
140
- boxLine(` GET ${healthUrl}`, ` ${chalk_1.default.dim('GET')} ${chalk_1.default.cyan(healthUrl)}`);
101
+ boxLine(` POST ${mcpUrl}`, ` ${chalk.dim('POST')} ${chalk.cyan(mcpUrl)}`);
102
+ boxLine(` GET ${healthUrl}`, ` ${chalk.dim('GET')} ${chalk.cyan(healthUrl)}`);
141
103
  boxDivider();
142
104
  const activeLabel = ` Tools (${activeTools.length} active${inactiveTools.length > 0 ? ` · ${inactiveTools.length} off` : ''})`;
143
- boxLine(activeLabel, chalk_1.default.dim(activeLabel));
105
+ boxLine(activeLabel, chalk.dim(activeLabel));
144
106
  for (const line of groupTools(activeTools)) {
145
107
  boxLine(` ${line}`, ` ${line}`);
146
108
  }
147
109
  if (inactiveTools.length > 0) {
148
110
  boxDivider();
149
- boxLine(' Off (enable in infrawise.yaml):', chalk_1.default.dim(' Off (enable in infrawise.yaml):'));
111
+ boxLine(' Off (enable in infrawise.yaml):', chalk.dim(' Off (enable in infrawise.yaml):'));
150
112
  for (const line of groupTools(inactiveTools)) {
151
- boxLine(` ${line}`, chalk_1.default.dim(` ${line}`));
113
+ boxLine(` ${line}`, chalk.dim(` ${line}`));
152
114
  }
153
115
  }
154
- console.log(chalk_1.default.dim(' └────────────────────────────────────────────────────┘'));
116
+ console.log(chalk.dim(' └────────────────────────────────────────────────────┘'));
155
117
  console.log('');
156
- console.log(chalk_1.default.dim(' Add via CLI:'));
157
- console.log(chalk_1.default.dim(` claude mcp add --transport http infrawise ${mcpUrl}`));
118
+ console.log(chalk.dim(' Add via CLI:'));
119
+ console.log(chalk.dim(` claude mcp add --transport http infrawise ${mcpUrl}`));
158
120
  console.log('');
159
- console.log(chalk_1.default.dim(' Watching for file changes... Press Ctrl+C to stop\n'));
121
+ console.log(chalk.dim(' Watching for file changes... Press Ctrl+C to stop\n'));
160
122
  // File watch — re-run code analysis on save, skip slow AWS/DB extraction
161
123
  let debounceTimer = null;
162
124
  let refreshing = false;
@@ -167,7 +129,7 @@ async function runDev(options = {}) {
167
129
  return;
168
130
  const abs = path.join(repoPath, filename);
169
131
  if (abs === configFile) {
170
- console.log(chalk_1.default.dim('\n infrawise.yaml changed — restart to apply config changes\n'));
132
+ console.log(chalk.dim('\n infrawise.yaml changed — restart to apply config changes\n'));
171
133
  return;
172
134
  }
173
135
  const ext = path.extname(filename);
@@ -181,14 +143,14 @@ async function runDev(options = {}) {
181
143
  if (refreshing)
182
144
  return;
183
145
  refreshing = true;
184
- const spin = (0, ora_1.default)({ text: chalk_1.default.dim('Refreshing code analysis...'), color: 'cyan' }).start();
146
+ const spin = ora({ text: chalk.dim('Refreshing code analysis...'), color: 'cyan' }).start();
185
147
  try {
186
- const { graph, findings } = await (0, analyze_1.runCodeRefresh)(repoPath, config);
187
- (0, server_1.setGraphState)(graph, findings);
188
- spin.succeed(chalk_1.default.green('Analysis refreshed') + chalk_1.default.dim(` ${graph.nodes.length} nodes · ${findings.length} finding(s)`));
148
+ const { graph, findings } = await runCodeRefresh(repoPath, config);
149
+ setGraphState(graph, findings, config);
150
+ spin.succeed(chalk.green('Analysis refreshed') + chalk.dim(` ${graph.nodes.length} nodes · ${findings.length} finding(s)`));
189
151
  }
190
152
  catch (err) {
191
- spin.warn(chalk_1.default.yellow('Refresh failed') + chalk_1.default.dim(` ${err instanceof Error ? err.message : String(err)}`));
153
+ spin.warn(chalk.yellow('Refresh failed') + chalk.dim(` ${err instanceof Error ? err.message : String(err)}`));
192
154
  }
193
155
  finally {
194
156
  refreshing = false;
@@ -200,7 +162,7 @@ async function runDev(options = {}) {
200
162
  // fs.watch may not support recursive on all platforms — silently skip
201
163
  }
202
164
  process.on('SIGINT', () => {
203
- console.log(chalk_1.default.dim('\n Shutting down...\n'));
165
+ console.log(chalk.dim('\n Shutting down...\n'));
204
166
  process.exit(0);
205
167
  });
206
168
  await new Promise(() => { });
@@ -1,78 +1,39 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.runDoctor = runDoctor;
40
- const fs = __importStar(require("fs"));
41
- const path = __importStar(require("path"));
42
- const os = __importStar(require("os"));
43
- const chalk_1 = __importDefault(require("chalk"));
44
- const ora_1 = __importDefault(require("ora"));
45
- const core_1 = require("../../core");
46
- const dynamodb_1 = require("../../adapters/dynamodb");
47
- const postgres_1 = require("../../adapters/postgres");
48
- const mysql_1 = require("../../adapters/mysql");
49
- const mongodb_1 = require("../../adapters/mongodb");
50
- const aws_1 = require("../../adapters/aws");
51
- const logs_1 = require("../../adapters/logs");
52
- const utils_1 = require("../utils");
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { loadConfig } from '../../core/index.js';
7
+ import { probeDynamoAccess } from '../../adapters/dynamodb.js';
8
+ import { validatePostgresAccess } from '../../adapters/postgres.js';
9
+ import { validateMySQLAccess } from '../../adapters/mysql.js';
10
+ import { validateMongoAccess } from '../../adapters/mongodb.js';
11
+ import { validateSQSAccess, validateSNSAccess, validateSSMAccess, validateSecretsAccess, validateLambdaAccess, validateEventBridgeAccess, } from '../../adapters/aws.js';
12
+ import { validateLogsAccess } from '../../adapters/logs.js';
13
+ import { printHeader } from '../utils.js';
53
14
  async function runCheck(label, fn) {
54
- const spin = (0, ora_1.default)({ text: chalk_1.default.dim(label), color: 'cyan' }).start();
15
+ const spin = ora({ text: chalk.dim(label), color: 'cyan' }).start();
55
16
  const result = await fn();
56
17
  switch (result.status) {
57
18
  case 'pass':
58
- spin.succeed(chalk_1.default.green(result.name) + chalk_1.default.dim(` ${result.message}`));
19
+ spin.succeed(chalk.green(result.name) + chalk.dim(` ${result.message}`));
59
20
  break;
60
21
  case 'fail':
61
- spin.fail(chalk_1.default.red(result.name) + chalk_1.default.dim(` ${result.message}`));
22
+ spin.fail(chalk.red(result.name) + chalk.dim(` ${result.message}`));
62
23
  break;
63
24
  case 'warn':
64
- spin.warn(chalk_1.default.yellow(result.name) + chalk_1.default.dim(` ${result.message}`));
25
+ spin.warn(chalk.yellow(result.name) + chalk.dim(` ${result.message}`));
65
26
  break;
66
27
  case 'skip':
67
- spin.info(chalk_1.default.dim(`${result.name} ${result.message}`));
28
+ spin.info(chalk.dim(`${result.name} ${result.message}`));
68
29
  break;
69
30
  }
70
31
  if (result.detail)
71
- console.log(chalk_1.default.dim(` ${result.detail}`));
32
+ console.log(chalk.dim(` ${result.detail}`));
72
33
  return result;
73
34
  }
74
- async function runDoctor(options = {}) {
75
- (0, utils_1.printHeader)('Infrawise Doctor');
35
+ export async function runDoctor(options = {}) {
36
+ printHeader('Infrawise Doctor');
76
37
  const configPath = path.resolve(options.config ?? 'infrawise.yaml');
77
38
  const results = [];
78
39
  // Config file
@@ -91,7 +52,7 @@ async function runDoctor(options = {}) {
91
52
  if (!fs.existsSync(configPath))
92
53
  return { name: 'Config validation', status: 'skip', message: 'No config file' };
93
54
  try {
94
- config = (0, core_1.loadConfig)(options.config);
55
+ config = loadConfig(options.config);
95
56
  return { name: 'Config validation', status: 'pass', message: `project: ${config.project}` };
96
57
  }
97
58
  catch (err) {
@@ -121,7 +82,7 @@ async function runDoctor(options = {}) {
121
82
  if (config.dynamodb?.enabled !== true)
122
83
  return { name: 'DynamoDB', status: 'skip', message: 'Disabled in config' };
123
84
  try {
124
- await (0, dynamodb_1.probeDynamoAccess)(config);
85
+ await probeDynamoAccess(config);
125
86
  return { name: 'DynamoDB', status: 'pass', message: `Connected (profile: ${config.aws?.profile ?? 'default'})` };
126
87
  }
127
88
  catch (err) {
@@ -137,7 +98,7 @@ async function runDoctor(options = {}) {
137
98
  if (config?.sqs?.enabled !== true)
138
99
  return { name: 'SQS', status: 'skip', message: 'Disabled in config' };
139
100
  try {
140
- await (0, aws_1.validateSQSAccess)(awsCfg);
101
+ await validateSQSAccess(awsCfg);
141
102
  return { name: 'SQS', status: 'pass', message: 'Connected' };
142
103
  }
143
104
  catch (err) {
@@ -153,7 +114,7 @@ async function runDoctor(options = {}) {
153
114
  if (config?.sns?.enabled !== true)
154
115
  return { name: 'SNS', status: 'skip', message: 'Disabled in config' };
155
116
  try {
156
- await (0, aws_1.validateSNSAccess)(awsCfg);
117
+ await validateSNSAccess(awsCfg);
157
118
  return { name: 'SNS', status: 'pass', message: 'Connected' };
158
119
  }
159
120
  catch (err) {
@@ -169,7 +130,7 @@ async function runDoctor(options = {}) {
169
130
  if (config?.ssm?.enabled !== true)
170
131
  return { name: 'SSM', status: 'skip', message: 'Disabled in config' };
171
132
  try {
172
- await (0, aws_1.validateSSMAccess)(awsCfg);
133
+ await validateSSMAccess(awsCfg);
173
134
  return { name: 'SSM', status: 'pass', message: 'Connected (metadata only)' };
174
135
  }
175
136
  catch (err) {
@@ -185,7 +146,7 @@ async function runDoctor(options = {}) {
185
146
  if (config?.secretsManager?.enabled !== true)
186
147
  return { name: 'Secrets Manager', status: 'skip', message: 'Disabled in config' };
187
148
  try {
188
- await (0, aws_1.validateSecretsAccess)(awsCfg);
149
+ await validateSecretsAccess(awsCfg);
189
150
  return { name: 'Secrets Manager', status: 'pass', message: 'Connected (names/rotation only)' };
190
151
  }
191
152
  catch (err) {
@@ -201,7 +162,7 @@ async function runDoctor(options = {}) {
201
162
  if (config?.lambda?.enabled !== true)
202
163
  return { name: 'Lambda', status: 'skip', message: 'Disabled in config' };
203
164
  try {
204
- await (0, aws_1.validateLambdaAccess)(awsCfg);
165
+ await validateLambdaAccess(awsCfg);
205
166
  return { name: 'Lambda', status: 'pass', message: 'Connected' };
206
167
  }
207
168
  catch (err) {
@@ -212,12 +173,28 @@ async function runDoctor(options = {}) {
212
173
  };
213
174
  }
214
175
  }));
176
+ // EventBridge
177
+ results.push(await runCheck('Testing EventBridge access...', async () => {
178
+ if (config?.eventbridge?.enabled !== true)
179
+ return { name: 'EventBridge', status: 'skip', message: 'Disabled in config' };
180
+ try {
181
+ await validateEventBridgeAccess(awsCfg);
182
+ return { name: 'EventBridge', status: 'pass', message: 'Connected' };
183
+ }
184
+ catch (err) {
185
+ return {
186
+ name: 'EventBridge', status: 'warn',
187
+ message: err instanceof Error ? err.message : String(err),
188
+ detail: 'Check IAM: events:ListRules, events:ListTargetsByRule',
189
+ };
190
+ }
191
+ }));
215
192
  // CloudWatch Logs
216
193
  results.push(await runCheck('Testing CloudWatch Logs access...', async () => {
217
194
  if (!config?.cloudwatchLogs?.enabled)
218
195
  return { name: 'CloudWatch Logs', status: 'skip', message: 'Not enabled in config' };
219
196
  try {
220
- await (0, logs_1.validateLogsAccess)(awsCfg);
197
+ await validateLogsAccess(awsCfg);
221
198
  return { name: 'CloudWatch Logs', status: 'pass', message: 'Connected' };
222
199
  }
223
200
  catch (err) {
@@ -234,7 +211,7 @@ async function runDoctor(options = {}) {
234
211
  return { name: 'PostgreSQL', status: 'skip', message: 'Not configured' };
235
212
  }
236
213
  try {
237
- const ok = await (0, postgres_1.validatePostgresAccess)(config.postgres.connectionString);
214
+ const ok = await validatePostgresAccess(config.postgres.connectionString);
238
215
  return {
239
216
  name: 'PostgreSQL', status: ok ? 'pass' : 'fail',
240
217
  message: ok ? 'Connected' : 'Cannot connect',
@@ -251,7 +228,7 @@ async function runDoctor(options = {}) {
251
228
  return { name: 'MySQL', status: 'skip', message: 'Not configured' };
252
229
  }
253
230
  try {
254
- const ok = await (0, mysql_1.validateMySQLAccess)(config.mysql.connectionString);
231
+ const ok = await validateMySQLAccess(config.mysql.connectionString);
255
232
  return {
256
233
  name: 'MySQL', status: ok ? 'pass' : 'fail',
257
234
  message: ok ? 'Connected' : 'Cannot connect',
@@ -268,7 +245,7 @@ async function runDoctor(options = {}) {
268
245
  return { name: 'MongoDB', status: 'skip', message: 'Not configured' };
269
246
  }
270
247
  try {
271
- const ok = await (0, mongodb_1.validateMongoAccess)(config.mongodb.connectionString);
248
+ const ok = await validateMongoAccess(config.mongodb.connectionString);
272
249
  return {
273
250
  name: 'MongoDB', status: ok ? 'pass' : 'fail',
274
251
  message: ok ? 'Connected' : 'Cannot connect',
@@ -329,12 +306,12 @@ async function runDoctor(options = {}) {
329
306
  const failed = results.filter((r) => r.status === 'fail').length;
330
307
  const warned = results.filter((r) => r.status === 'warn').length;
331
308
  console.log('');
332
- console.log(chalk_1.default.dim(' ' + '─'.repeat(40)));
309
+ console.log(chalk.dim(' ' + '─'.repeat(40)));
333
310
  if (failed === 0) {
334
- console.log(` ${chalk_1.default.green.bold('All checks passed')} ${chalk_1.default.dim(`${passed} passed, ${warned} warning(s)`)}`);
311
+ console.log(` ${chalk.green.bold('All checks passed')} ${chalk.dim(`${passed} passed, ${warned} warning(s)`)}`);
335
312
  }
336
313
  else {
337
- console.log(` ${chalk_1.default.red.bold(`${failed} check(s) failed`)} ${chalk_1.default.dim(`${passed} passed, ${warned} warning(s)`)}`);
314
+ console.log(` ${chalk.red.bold(`${failed} check(s) failed`)} ${chalk.dim(`${passed} passed, ${warned} warning(s)`)}`);
338
315
  }
339
316
  console.log('');
340
317
  if (failed > 0)