@syntero/orca-cli 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.
package/dist/tools.js ADDED
@@ -0,0 +1,359 @@
1
+ import { execSync, spawnSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import Database from 'better-sqlite3';
5
+ import { getDeploymentDir } from './settings.js';
6
+ import { redactSecrets, isSecretKey } from './utils.js';
7
+ // Tool definitions for Anthropic format
8
+ export const TOOLS_ANTHROPIC = [
9
+ {
10
+ name: 'run_command',
11
+ description: `Execute a shell command and return output. Use for:
12
+ - Docker commands: docker ps, docker logs, docker inspect, docker stats, docker network ls
13
+ - System info: df -h, free -m, uname -a, whoami, id
14
+ - File listing: ls -la <path>
15
+ - Process info: ps aux | grep <pattern>
16
+ - Network: netstat -tlnp, curl -I <url>
17
+
18
+ Commands run with a 30-second timeout. For docker logs, use --tail to limit output.`,
19
+ input_schema: {
20
+ type: 'object',
21
+ properties: {
22
+ command: { type: 'string', description: 'The shell command to execute' },
23
+ },
24
+ required: ['command'],
25
+ },
26
+ },
27
+ {
28
+ name: 'read_file',
29
+ description: `Read the contents of a file. Use for config files, logs, etc.
30
+ Paths can be absolute or relative to the deployment directory.
31
+ Do not read .env directly - use inspect_env instead.`,
32
+ input_schema: {
33
+ type: 'object',
34
+ properties: {
35
+ path: { type: 'string', description: 'Path to the file' },
36
+ tail: { type: 'integer', description: 'Only return the last N lines' },
37
+ },
38
+ required: ['path'],
39
+ },
40
+ },
41
+ {
42
+ name: 'list_directory',
43
+ description: 'List contents of a directory with details.',
44
+ input_schema: {
45
+ type: 'object',
46
+ properties: {
47
+ path: { type: 'string', description: 'Directory path' },
48
+ },
49
+ required: ['path'],
50
+ },
51
+ },
52
+ {
53
+ name: 'inspect_env',
54
+ description: 'Safely inspect .env configuration with secrets redacted.',
55
+ input_schema: {
56
+ type: 'object',
57
+ properties: {
58
+ show_all: { type: 'boolean', description: 'Show all variables (secrets still redacted)' },
59
+ },
60
+ },
61
+ },
62
+ {
63
+ name: 'query_database',
64
+ description: 'Execute a READ-ONLY SQL query on the main SQLite database. Only SELECT allowed.',
65
+ input_schema: {
66
+ type: 'object',
67
+ properties: {
68
+ query: { type: 'string', description: 'SQL SELECT query to execute' },
69
+ },
70
+ required: ['query'],
71
+ },
72
+ },
73
+ {
74
+ name: 'search_logs',
75
+ description: 'Search through docker logs for a pattern.',
76
+ input_schema: {
77
+ type: 'object',
78
+ properties: {
79
+ container: { type: 'string', description: 'Container name' },
80
+ pattern: { type: 'string', description: 'Grep pattern to search for' },
81
+ case_insensitive: { type: 'boolean', description: 'Case insensitive search' },
82
+ context_lines: { type: 'integer', description: 'Context lines before/after match' },
83
+ },
84
+ required: ['container', 'pattern'],
85
+ },
86
+ },
87
+ {
88
+ name: 'check_container_health',
89
+ description: 'Get a comprehensive health report for Orca containers.',
90
+ input_schema: {
91
+ type: 'object',
92
+ properties: {
93
+ container: { type: 'string', description: "Container name or 'all'" },
94
+ },
95
+ },
96
+ },
97
+ ];
98
+ // Convert to OpenAI format
99
+ export const TOOLS_OPENAI = TOOLS_ANTHROPIC.map((tool) => ({
100
+ type: 'function',
101
+ function: {
102
+ name: tool.name,
103
+ description: tool.description,
104
+ parameters: tool.input_schema,
105
+ },
106
+ }));
107
+ /**
108
+ * Resolve a path relative to deployment directory.
109
+ */
110
+ function resolvePath(filePath) {
111
+ const p = path.isAbsolute(filePath) ? filePath : path.join(getDeploymentDir(), filePath);
112
+ return p;
113
+ }
114
+ /**
115
+ * Execute a shell command with timeout.
116
+ */
117
+ export function runCommand(command, timeout = 30000) {
118
+ const dangerous = ['rm -rf', 'mkfs', 'dd if=', ':(){', 'fork bomb', '> /dev/sd', 'chmod -R 777 /'];
119
+ for (const d of dangerous) {
120
+ if (command.toLowerCase().includes(d)) {
121
+ return `Error: Blocked potentially dangerous command containing '${d}'`;
122
+ }
123
+ }
124
+ try {
125
+ const result = execSync(command, {
126
+ timeout,
127
+ encoding: 'utf-8',
128
+ cwd: getDeploymentDir(),
129
+ stdio: ['pipe', 'pipe', 'pipe'],
130
+ });
131
+ let output = result;
132
+ if (output.length > 50000) {
133
+ output = output.slice(0, 50000) + '\n... [truncated]';
134
+ }
135
+ return redactSecrets(output) || '(no output)';
136
+ }
137
+ catch (e) {
138
+ if (e && typeof e === 'object' && 'killed' in e && e.killed) {
139
+ return `Error: Command timed out after ${timeout / 1000} seconds`;
140
+ }
141
+ if (e && typeof e === 'object' && 'stderr' in e && 'stdout' in e) {
142
+ const execError = e;
143
+ const stderr = execError.stderr
144
+ ? typeof execError.stderr === 'string'
145
+ ? execError.stderr
146
+ : execError.stderr.toString()
147
+ : '';
148
+ const stdout = execError.stdout
149
+ ? typeof execError.stdout === 'string'
150
+ ? execError.stdout
151
+ : execError.stdout.toString()
152
+ : '';
153
+ const output = stdout + stderr;
154
+ return redactSecrets(output) || `Error: ${e instanceof Error ? e.message : String(e)}`;
155
+ }
156
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
157
+ }
158
+ }
159
+ /**
160
+ * Read a file's contents.
161
+ */
162
+ export function readFile(filePath, tail) {
163
+ const resolved = resolvePath(filePath);
164
+ if (path.basename(resolved) === '.env' && !resolved.includes('.template')) {
165
+ return 'Error: Use inspect_env tool to safely view environment variables.';
166
+ }
167
+ try {
168
+ let content = fs.readFileSync(resolved, 'utf-8');
169
+ if (tail) {
170
+ const lines = content.split('\n');
171
+ content = lines.slice(-tail).join('\n');
172
+ }
173
+ if (content.length > 100000) {
174
+ content = content.slice(0, 100000) + '\n... [truncated]';
175
+ }
176
+ return content;
177
+ }
178
+ catch (e) {
179
+ if (e && typeof e === 'object' && 'code' in e && e.code === 'ENOENT') {
180
+ return `Error: File not found: ${resolved}`;
181
+ }
182
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
183
+ }
184
+ }
185
+ /**
186
+ * List directory contents.
187
+ */
188
+ export function listDirectory(dirPath) {
189
+ const resolved = resolvePath(dirPath);
190
+ try {
191
+ const result = spawnSync('ls', ['-la', resolved], { encoding: 'utf-8' });
192
+ return result.stdout + result.stderr;
193
+ }
194
+ catch (e) {
195
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
196
+ }
197
+ }
198
+ /**
199
+ * Inspect .env file with secrets redacted.
200
+ */
201
+ export function inspectEnv(showAll = false) {
202
+ const envPath = path.join(getDeploymentDir(), '.env');
203
+ if (!fs.existsSync(envPath)) {
204
+ return `No .env file found at ${envPath}`;
205
+ }
206
+ const result = [];
207
+ const content = fs.readFileSync(envPath, 'utf-8');
208
+ for (const line of content.split('\n')) {
209
+ const trimmed = line.trim();
210
+ if (!trimmed || trimmed.startsWith('#')) {
211
+ result.push(trimmed);
212
+ continue;
213
+ }
214
+ if (trimmed.includes('=')) {
215
+ const [key, ...valueParts] = trimmed.split('=');
216
+ const value = valueParts.join('=').trim();
217
+ const keyTrimmed = key.trim();
218
+ if (isSecretKey(keyTrimmed)) {
219
+ if (value) {
220
+ result.push(`${keyTrimmed}=[REDACTED - ${value.length} chars]`);
221
+ }
222
+ else {
223
+ result.push(`${keyTrimmed}=[NOT SET]`);
224
+ }
225
+ }
226
+ else if (showAll || !isSecretKey(keyTrimmed)) {
227
+ result.push(`${keyTrimmed}=${value}`);
228
+ }
229
+ }
230
+ }
231
+ return result.join('\n');
232
+ }
233
+ /**
234
+ * Find the SQLite database path.
235
+ */
236
+ function findDatabasePath() {
237
+ const deploymentDir = getDeploymentDir();
238
+ const candidates = [
239
+ path.join(deploymentDir, 'data', 'main.db'),
240
+ path.join(deploymentDir, 'backend-data', 'main.db'),
241
+ ];
242
+ try {
243
+ const result = execSync('docker volume inspect backend-data --format "{{.Mountpoint}}"', { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
244
+ if (result) {
245
+ candidates.unshift(path.join(result, 'main.db'));
246
+ }
247
+ }
248
+ catch {
249
+ // Ignore errors
250
+ }
251
+ for (const dbPath of candidates) {
252
+ if (fs.existsSync(dbPath)) {
253
+ return dbPath;
254
+ }
255
+ }
256
+ return null;
257
+ }
258
+ /**
259
+ * Execute a read-only SQL query.
260
+ */
261
+ export function queryDatabase(query) {
262
+ const queryUpper = query.trim().toUpperCase();
263
+ if (!queryUpper.startsWith('SELECT')) {
264
+ return 'Error: Only SELECT queries are allowed.';
265
+ }
266
+ const dangerous = ['DROP', 'DELETE', 'INSERT', 'UPDATE', 'ALTER', 'CREATE', 'TRUNCATE'];
267
+ for (const d of dangerous) {
268
+ if (queryUpper.includes(d)) {
269
+ return `Error: Query contains blocked keyword: ${d}`;
270
+ }
271
+ }
272
+ const dbPath = findDatabasePath();
273
+ if (!dbPath) {
274
+ // Try via docker
275
+ return runCommand(`docker exec orca-backend sqlite3 /app/backend/data/main.db "${query}"`);
276
+ }
277
+ try {
278
+ const db = new Database(dbPath, { readonly: true });
279
+ const stmt = db.prepare(query);
280
+ const rows = stmt.all();
281
+ if (rows.length === 0) {
282
+ db.close();
283
+ return '(no results)';
284
+ }
285
+ const columns = Object.keys(rows[0]);
286
+ const result = [columns.join('\t'), '-'.repeat(40)];
287
+ for (const row of rows.slice(0, 100)) {
288
+ result.push(columns.map((col) => String(row[col])).join('\t'));
289
+ }
290
+ if (rows.length > 100) {
291
+ result.push(`... (${rows.length - 100} more rows)`);
292
+ }
293
+ db.close();
294
+ return result.join('\n');
295
+ }
296
+ catch (e) {
297
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
298
+ }
299
+ }
300
+ /**
301
+ * Search container logs for a pattern.
302
+ */
303
+ export function searchLogs(container, pattern, caseInsensitive = true, contextLines = 2) {
304
+ let grepFlags = caseInsensitive ? '-i' : '';
305
+ if (contextLines) {
306
+ grepFlags += ` -C ${contextLines}`;
307
+ }
308
+ return runCommand(`docker logs ${container} 2>&1 | grep ${grepFlags} "${pattern}" | tail -100`);
309
+ }
310
+ /**
311
+ * Check health of Orca containers.
312
+ */
313
+ export function checkContainerHealth(container = 'all') {
314
+ const result = [];
315
+ let containers;
316
+ if (container === 'all') {
317
+ containers = ['orca-backend', 'orca-frontend', 'orca-redis'];
318
+ const psResult = runCommand('docker ps -a --filter "name=orca-" --format "{{.Names}}"');
319
+ for (const name of psResult.trim().split('\n')) {
320
+ if (name && !containers.includes(name)) {
321
+ containers.push(name);
322
+ }
323
+ }
324
+ }
325
+ else {
326
+ containers = [container];
327
+ }
328
+ for (const c of containers) {
329
+ result.push(`\n${'='.repeat(60)}\nContainer: ${c}\n${'='.repeat(60)}`);
330
+ result.push(runCommand(`docker inspect ${c} --format "Status: {{.State.Status}}, Restarts: {{.RestartCount}}"`));
331
+ const stats = runCommand(`docker stats ${c} --no-stream --format "CPU: {{.CPUPerc}}, Mem: {{.MemUsage}}"`);
332
+ if (!stats.includes('Error')) {
333
+ result.push(stats);
334
+ }
335
+ result.push('\nRecent logs (last 10 lines):');
336
+ result.push(runCommand(`docker logs ${c} --tail 10 2>&1`));
337
+ }
338
+ return result.join('\n');
339
+ }
340
+ /**
341
+ * Handle a tool call and return the result.
342
+ */
343
+ export function handleToolCall(name, inputData) {
344
+ const handlers = {
345
+ run_command: () => runCommand(inputData.command),
346
+ read_file: () => readFile(inputData.path, inputData.tail),
347
+ list_directory: () => listDirectory(inputData.path),
348
+ inspect_env: () => inspectEnv(inputData.show_all || false),
349
+ query_database: () => queryDatabase(inputData.query),
350
+ search_logs: () => searchLogs(inputData.container, inputData.pattern, inputData.case_insensitive ?? true, inputData.context_lines ?? 2),
351
+ check_container_health: () => checkContainerHealth(inputData.container || 'all'),
352
+ };
353
+ const handler = handlers[name];
354
+ if (handler) {
355
+ return handler();
356
+ }
357
+ return `Unknown tool: ${name}`;
358
+ }
359
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import * as readline from 'readline';
2
+ export declare const Colors: {
3
+ blue: import("chalk").ChalkInstance;
4
+ green: import("chalk").ChalkInstance;
5
+ yellow: import("chalk").ChalkInstance;
6
+ red: import("chalk").ChalkInstance;
7
+ cyan: import("chalk").ChalkInstance;
8
+ dim: import("chalk").ChalkInstance;
9
+ bold: import("chalk").ChalkInstance;
10
+ };
11
+ export declare function color(text: string, colorFn: (s: string) => string): string;
12
+ export declare class CancelledError extends Error {
13
+ constructor(message?: string);
14
+ }
15
+ export declare function maskSecret(secret: string): string;
16
+ /**
17
+ * Create a readline interface for user input
18
+ */
19
+ export declare function createReadlineInterface(): readline.Interface;
20
+ /**
21
+ * Prompt for input with optional default and secret masking.
22
+ * Type 'q' or 'cancel' to abort. Press Ctrl+C to cancel.
23
+ */
24
+ export declare function promptInput(prompt: string, defaultValue?: string, options?: {
25
+ secret?: boolean;
26
+ allowCancel?: boolean;
27
+ }): Promise<string>;
28
+ /**
29
+ * Wait for a single keypress
30
+ */
31
+ export declare function waitForKeypress(): Promise<string>;
32
+ /**
33
+ * Redact potential secrets from text output
34
+ */
35
+ export declare function redactSecrets(text: string): string;
36
+ /**
37
+ * Check if an environment variable key is likely a secret
38
+ */
39
+ export declare function isSecretKey(key: string): boolean;
40
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAGrC,eAAO,MAAM,MAAM;;;;;;;;CAQlB,CAAC;AAEF,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAK1E;AAED,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,SAAwB;CAI5C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,QAAQ,CAAC,SAAS,CAK5D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,YAAY,SAAK,EACjB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACxD,OAAO,CAAC,MAAM,CAAC,CAuFjB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAoBjD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAalD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWhD"}
package/dist/utils.js ADDED
@@ -0,0 +1,178 @@
1
+ import chalk from 'chalk';
2
+ import * as readline from 'readline';
3
+ // Terminal colors
4
+ export const Colors = {
5
+ blue: chalk.blue,
6
+ green: chalk.green,
7
+ yellow: chalk.yellow,
8
+ red: chalk.red,
9
+ cyan: chalk.cyan,
10
+ dim: chalk.dim,
11
+ bold: chalk.bold,
12
+ };
13
+ export function color(text, colorFn) {
14
+ if (!process.stdout.isTTY) {
15
+ return text;
16
+ }
17
+ return colorFn(text);
18
+ }
19
+ export class CancelledError extends Error {
20
+ constructor(message = 'Operation cancelled') {
21
+ super(message);
22
+ this.name = 'CancelledError';
23
+ }
24
+ }
25
+ export function maskSecret(secret) {
26
+ if (!secret) {
27
+ return color('(not set)', Colors.dim);
28
+ }
29
+ if (secret.length <= 8) {
30
+ return '****';
31
+ }
32
+ return `${secret.slice(0, 4)}...${secret.slice(-4)}`;
33
+ }
34
+ /**
35
+ * Create a readline interface for user input
36
+ */
37
+ export function createReadlineInterface() {
38
+ return readline.createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ });
42
+ }
43
+ /**
44
+ * Prompt for input with optional default and secret masking.
45
+ * Type 'q' or 'cancel' to abort. Press Ctrl+C to cancel.
46
+ */
47
+ export async function promptInput(prompt, defaultValue = '', options = {}) {
48
+ const { secret = false, allowCancel = true } = options;
49
+ const cancelHint = allowCancel ? color(' (q to cancel)', Colors.dim) : '';
50
+ let displayPrompt;
51
+ if (defaultValue) {
52
+ const displayDefault = secret ? maskSecret(defaultValue) : defaultValue;
53
+ displayPrompt = `${prompt} [${displayDefault}]${cancelHint}: `;
54
+ }
55
+ else {
56
+ displayPrompt = `${prompt}${cancelHint}: `;
57
+ }
58
+ return new Promise((resolve, reject) => {
59
+ if (secret) {
60
+ // Hidden input for secrets
61
+ process.stdout.write(displayPrompt);
62
+ const stdin = process.stdin;
63
+ const wasRaw = stdin.isRaw;
64
+ if (stdin.isTTY) {
65
+ stdin.setRawMode(true);
66
+ }
67
+ stdin.resume();
68
+ let input = '';
69
+ const handleData = (char) => {
70
+ const c = char.toString();
71
+ if (c === '\n' || c === '\r') {
72
+ stdin.removeListener('data', handleData);
73
+ if (stdin.isTTY) {
74
+ stdin.setRawMode(wasRaw || false);
75
+ }
76
+ process.stdout.write('\n');
77
+ const value = input.trim();
78
+ if (allowCancel && ['q', 'quit', 'cancel', 'exit'].includes(value.toLowerCase())) {
79
+ reject(new CancelledError());
80
+ return;
81
+ }
82
+ resolve(value || defaultValue);
83
+ }
84
+ else if (c === '\u0003') {
85
+ // Ctrl+C
86
+ stdin.removeListener('data', handleData);
87
+ if (stdin.isTTY) {
88
+ stdin.setRawMode(wasRaw || false);
89
+ }
90
+ process.stdout.write('\n');
91
+ reject(new CancelledError());
92
+ }
93
+ else if (c === '\u007f' || c === '\b') {
94
+ // Backspace
95
+ if (input.length > 0) {
96
+ input = input.slice(0, -1);
97
+ }
98
+ }
99
+ else if (c.charCodeAt(0) >= 32) {
100
+ input += c;
101
+ }
102
+ };
103
+ stdin.on('data', handleData);
104
+ }
105
+ else {
106
+ // Normal input
107
+ const rl = createReadlineInterface();
108
+ const handleSigint = () => {
109
+ rl.close();
110
+ process.stdout.write('\n');
111
+ reject(new CancelledError());
112
+ };
113
+ rl.once('SIGINT', handleSigint);
114
+ rl.question(displayPrompt, (answer) => {
115
+ rl.removeListener('SIGINT', handleSigint);
116
+ rl.close();
117
+ const value = answer.trim();
118
+ if (allowCancel && ['q', 'quit', 'cancel', 'exit'].includes(value.toLowerCase())) {
119
+ reject(new CancelledError());
120
+ return;
121
+ }
122
+ resolve(value || defaultValue);
123
+ });
124
+ }
125
+ });
126
+ }
127
+ /**
128
+ * Wait for a single keypress
129
+ */
130
+ export function waitForKeypress() {
131
+ return new Promise((resolve) => {
132
+ const stdin = process.stdin;
133
+ const wasRaw = stdin.isRaw;
134
+ if (stdin.isTTY) {
135
+ stdin.setRawMode(true);
136
+ }
137
+ stdin.resume();
138
+ const handleKey = (key) => {
139
+ stdin.removeListener('data', handleKey);
140
+ if (stdin.isTTY) {
141
+ stdin.setRawMode(wasRaw || false);
142
+ }
143
+ resolve(key.toString());
144
+ };
145
+ stdin.once('data', handleKey);
146
+ });
147
+ }
148
+ /**
149
+ * Redact potential secrets from text output
150
+ */
151
+ export function redactSecrets(text) {
152
+ const patterns = [
153
+ { pattern: /(password["\s:=]+)[^\s"]+/gi, replacement: '$1[REDACTED]' },
154
+ { pattern: /(secret["\s:=]+)[^\s"]+/gi, replacement: '$1[REDACTED]' },
155
+ { pattern: /(token["\s:=]+)[^\s"]+/gi, replacement: '$1[REDACTED]' },
156
+ { pattern: /(api[_-]?key["\s:=]+)[^\s"]+/gi, replacement: '$1[REDACTED]' },
157
+ ];
158
+ let result = text;
159
+ for (const { pattern, replacement } of patterns) {
160
+ result = result.replace(pattern, replacement);
161
+ }
162
+ return result;
163
+ }
164
+ /**
165
+ * Check if an environment variable key is likely a secret
166
+ */
167
+ export function isSecretKey(key) {
168
+ const patterns = [
169
+ /.*(_KEY|_SECRET|_PASSWORD|_TOKEN|_CREDENTIALS)$/i,
170
+ /^(PASSWORD|SECRET|TOKEN|PRIVATE_KEY|API_KEY)$/i,
171
+ /.*_API_KEY$/i,
172
+ /^NEO4J_PASSWORD$/i,
173
+ /^FLASK_SECRET_KEY$/i,
174
+ /^REGISTRATION_PASSCODE$/i,
175
+ ];
176
+ return patterns.some((pattern) => pattern.test(key));
177
+ }
178
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@syntero/orca-cli",
3
+ "version": "1.0.0",
4
+ "description": "LLM-powered deployment troubleshooting assistant for Orca",
5
+ "type": "module",
6
+ "bin": {
7
+ "orca": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsc && node dist/index.js",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "deployment",
21
+ "assistant",
22
+ "llm",
23
+ "orca",
24
+ "cli",
25
+ "troubleshooting"
26
+ ],
27
+ "author": "Syntero",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/syntero/orca.git"
32
+ },
33
+ "homepage": "https://github.com/syntero/orca#readme",
34
+ "dependencies": {
35
+ "@anthropic-ai/sdk": "^0.71.2",
36
+ "better-sqlite3": "^12.6.2",
37
+ "chalk": "^5.6.2",
38
+ "openai": "^6.16.0",
39
+ "update-notifier": "^7.3.1"
40
+ },
41
+ "devDependencies": {
42
+ "@types/better-sqlite3": "^7.6.12",
43
+ "@types/node": "^22.10.5",
44
+ "@types/update-notifier": "^6.0.8",
45
+ "typescript": "^5.7.2"
46
+ },
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ }
50
+ }