outlet-orm 6.5.0 ā 9.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/README.md +130 -2
- package/bin/init.js +122 -0
- package/bin/mcp.js +78 -0
- package/bin/migrate.js +25 -0
- package/docs/skills/outlet-orm/ADVANCED.md +575 -0
- package/docs/skills/outlet-orm/AI.md +220 -0
- package/docs/skills/outlet-orm/API.md +522 -0
- package/docs/skills/outlet-orm/BACKUP.md +150 -0
- package/docs/skills/outlet-orm/MIGRATIONS.md +605 -0
- package/docs/skills/outlet-orm/MODELS.md +427 -0
- package/docs/skills/outlet-orm/QUERIES.md +345 -0
- package/docs/skills/outlet-orm/RELATIONS.md +555 -0
- package/docs/skills/outlet-orm/SECURITY.md +386 -0
- package/docs/skills/outlet-orm/SEEDS.md +98 -0
- package/docs/skills/outlet-orm/SKILL.md +205 -0
- package/docs/skills/outlet-orm/TYPESCRIPT.md +480 -0
- package/package.json +7 -3
- package/src/AI/AIPromptEnhancer.js +170 -0
- package/src/AI/AIQueryBuilder.js +234 -0
- package/src/AI/AIQueryOptimizer.js +185 -0
- package/src/AI/AISafetyGuardrails.js +146 -0
- package/src/AI/AISeeder.js +181 -0
- package/src/AI/AiBridgeManager.js +287 -0
- package/src/AI/Builders/TextBuilder.js +170 -0
- package/src/AI/Contracts/AudioProviderContract.js +29 -0
- package/src/AI/Contracts/ChatProviderContract.js +38 -0
- package/src/AI/Contracts/EmbeddingsProviderContract.js +19 -0
- package/src/AI/Contracts/ImageProviderContract.js +19 -0
- package/src/AI/Contracts/ModelsProviderContract.js +26 -0
- package/src/AI/Contracts/ToolContract.js +25 -0
- package/src/AI/Facades/AiBridge.js +79 -0
- package/src/AI/MCPServer.js +798 -0
- package/src/AI/PromptGenerator.js +318 -0
- package/src/AI/Providers/ClaudeProvider.js +64 -0
- package/src/AI/Providers/CustomOpenAIProvider.js +238 -0
- package/src/AI/Providers/GeminiProvider.js +68 -0
- package/src/AI/Providers/GrokProvider.js +46 -0
- package/src/AI/Providers/MistralProvider.js +21 -0
- package/src/AI/Providers/OllamaProvider.js +249 -0
- package/src/AI/Providers/OllamaTurboProvider.js +32 -0
- package/src/AI/Providers/OnnProvider.js +46 -0
- package/src/AI/Providers/OpenAIProvider.js +471 -0
- package/src/AI/Support/AudioNormalizer.js +37 -0
- package/src/AI/Support/ChatNormalizer.js +42 -0
- package/src/AI/Support/Document.js +77 -0
- package/src/AI/Support/DocumentAttachmentMapper.js +101 -0
- package/src/AI/Support/EmbeddingsNormalizer.js +30 -0
- package/src/AI/Support/Exceptions/ProviderError.js +22 -0
- package/src/AI/Support/FileSecurity.js +56 -0
- package/src/AI/Support/ImageNormalizer.js +62 -0
- package/src/AI/Support/JsonSchemaValidator.js +73 -0
- package/src/AI/Support/Message.js +40 -0
- package/src/AI/Support/StreamChunk.js +45 -0
- package/src/AI/Support/ToolChatRunner.js +160 -0
- package/src/AI/Support/ToolRegistry.js +62 -0
- package/src/AI/Tools/SystemInfoTool.js +25 -0
- package/src/index.js +77 -1
- package/types/index.d.ts +432 -0
package/README.md
CHANGED
|
@@ -197,7 +197,14 @@ async store(req, res) {
|
|
|
197
197
|
- **Raw queries**: `executeRawQuery()` and `execute()` (native driver results)
|
|
198
198
|
- **Complete Migrations** (create/alter/drop, index, foreign keys, batch tracking)
|
|
199
199
|
- **Database Backup** (v6.0.0): full/partial/journal backups, recurring scheduler, AES-256-GCM encryption, TCP daemon + remote client, automatic restore
|
|
200
|
-
- **
|
|
200
|
+
- **š¤ AiBridge** (v8.0.0): Multi-provider LLM abstraction ā chat, stream, embeddings, images, TTS, STT with 9+ providers
|
|
201
|
+
- **š¤ AI Query Builder** (v8.0.0): Natural language ā SQL with schema introspection
|
|
202
|
+
- **š¤ AI Seeder** (v8.0.0): LLM-powered realistic, domain-specific data generation
|
|
203
|
+
- **š¤ AI Query Optimizer** (v8.0.0): SQL analysis, optimization, and index recommendations
|
|
204
|
+
- **š¤ AI Prompt Enhancer** (v8.0.0): Schema/model/migration generation from natural language
|
|
205
|
+
- **š¤ MCP Server** (v7.0.0): Model Context Protocol for AI agent integration (13 tools)
|
|
206
|
+
- **š¤ AI Safety Guardrails** (v7.0.0): Automatic AI agent detection + destructive operation protection
|
|
207
|
+
- **Handy CLI tools**: `outlet-init`, `outlet-migrate`, `outlet-convert`, `outlet-mcp`
|
|
201
208
|
- **`.env` configuration** (loaded automatically)
|
|
202
209
|
- **Multi-database**: MySQL, PostgreSQL, and SQLite
|
|
203
210
|
- **Complete TypeScript types** with Generic Model and typed Schema Builder (v4.0.0+)
|
|
@@ -1220,6 +1227,126 @@ outlet-convert
|
|
|
1220
1227
|
- ā
Automatic timestamps support
|
|
1221
1228
|
- ā
Class names converted to PascalCase
|
|
1222
1229
|
|
|
1230
|
+
## š¤ AI Integration
|
|
1231
|
+
|
|
1232
|
+
Outlet ORM includes a complete AI subsystem with multi-provider LLM support and ORM-specific AI features.
|
|
1233
|
+
|
|
1234
|
+
š **[Complete AI documentation available in `/docs`](./docs/AI_BRIDGE.md)**
|
|
1235
|
+
|
|
1236
|
+
### AiBridge ā Multi-Provider LLM Abstraction
|
|
1237
|
+
|
|
1238
|
+
```javascript
|
|
1239
|
+
const { AiBridgeManager } = require('outlet-orm');
|
|
1240
|
+
|
|
1241
|
+
const ai = new AiBridgeManager({
|
|
1242
|
+
providers: {
|
|
1243
|
+
openai: { api_key: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
|
|
1244
|
+
claude: { api_key: process.env.ANTHROPIC_API_KEY, model: 'claude-sonnet-4-20250514' },
|
|
1245
|
+
ollama: { endpoint: 'http://localhost:11434', model: 'llama3' }
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
// Chat with any provider
|
|
1250
|
+
const response = await ai.chat('openai', [
|
|
1251
|
+
{ role: 'user', content: 'What is Node.js?' }
|
|
1252
|
+
]);
|
|
1253
|
+
|
|
1254
|
+
// Fluent TextBuilder
|
|
1255
|
+
const { text } = await ai.text()
|
|
1256
|
+
.using('openai', 'gpt-4o')
|
|
1257
|
+
.withSystemPrompt('You are a helpful assistant.')
|
|
1258
|
+
.withPrompt('Explain closures in JavaScript.')
|
|
1259
|
+
.asText();
|
|
1260
|
+
|
|
1261
|
+
// Stream responses
|
|
1262
|
+
for await (const chunk of ai.stream('claude', messages)) {
|
|
1263
|
+
process.stdout.write(chunk.text || '');
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
// Embeddings, images, TTS, STT
|
|
1267
|
+
const embeddings = await ai.embeddings('openai', ['Hello world']);
|
|
1268
|
+
const image = await ai.image('openai', 'A sunset over mountains');
|
|
1269
|
+
```
|
|
1270
|
+
|
|
1271
|
+
**Supported providers**: OpenAI, Claude, Gemini, Ollama, Grok, Mistral, ONN, Custom OpenAI, OpenRouter
|
|
1272
|
+
|
|
1273
|
+
### AI Query Builder ā Natural Language ā SQL
|
|
1274
|
+
|
|
1275
|
+
```javascript
|
|
1276
|
+
const { AIQueryBuilder } = require('outlet-orm');
|
|
1277
|
+
|
|
1278
|
+
const qb = new AIQueryBuilder(ai, db);
|
|
1279
|
+
|
|
1280
|
+
// Ask in natural language, get SQL + results
|
|
1281
|
+
const result = await qb.query('How many users signed up last month?');
|
|
1282
|
+
console.log(result.sql); // SELECT COUNT(*) FROM users WHERE ...
|
|
1283
|
+
console.log(result.results); // [{ count: 42 }]
|
|
1284
|
+
|
|
1285
|
+
// Generate SQL without executing
|
|
1286
|
+
const { sql } = await qb.toSql('Show me the top 5 users by post count');
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
### AI Seeder ā Realistic Data Generation
|
|
1290
|
+
|
|
1291
|
+
```javascript
|
|
1292
|
+
const { AISeeder } = require('outlet-orm');
|
|
1293
|
+
|
|
1294
|
+
const seeder = new AISeeder(ai, db);
|
|
1295
|
+
|
|
1296
|
+
// Generate and insert realistic data
|
|
1297
|
+
await seeder.seed('products', 20, {
|
|
1298
|
+
domain: 'e-commerce',
|
|
1299
|
+
locale: 'fr_FR',
|
|
1300
|
+
description: 'Fashion store for young adults'
|
|
1301
|
+
});
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
### AI Query Optimizer
|
|
1305
|
+
|
|
1306
|
+
```javascript
|
|
1307
|
+
const { AIQueryOptimizer } = require('outlet-orm');
|
|
1308
|
+
|
|
1309
|
+
const optimizer = new AIQueryOptimizer(ai, db);
|
|
1310
|
+
const result = await optimizer.optimize(
|
|
1311
|
+
'SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE status = "active")'
|
|
1312
|
+
);
|
|
1313
|
+
|
|
1314
|
+
console.log(result.optimized); // Rewritten SQL
|
|
1315
|
+
console.log(result.suggestions); // [{ type: 'index', impact: 'high', ... }]
|
|
1316
|
+
console.log(result.indexes); // ['CREATE INDEX idx_...']
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
### MCP Server ā AI Agent Integration
|
|
1320
|
+
|
|
1321
|
+
```bash
|
|
1322
|
+
# Start MCP server for AI editors
|
|
1323
|
+
npx outlet-mcp
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
Configure your AI editor:
|
|
1327
|
+
|
|
1328
|
+
```json
|
|
1329
|
+
{
|
|
1330
|
+
"mcpServers": {
|
|
1331
|
+
"outlet-orm": {
|
|
1332
|
+
"command": "npx",
|
|
1333
|
+
"args": ["outlet-mcp"]
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
```
|
|
1338
|
+
|
|
1339
|
+
**13 MCP tools**: migrations, schema introspection, queries, seeds, backups, AI query, query optimization
|
|
1340
|
+
|
|
1341
|
+
š Full documentation:
|
|
1342
|
+
- [AiBridge Manager](docs/AI_BRIDGE.md) ā Multi-provider LLM abstraction
|
|
1343
|
+
- [AI Query Builder](docs/AI_QUERY.md) ā Natural language to SQL
|
|
1344
|
+
- [AI Seeder](docs/AI_SEEDER.md) ā Realistic data generation
|
|
1345
|
+
- [AI Query Optimizer](docs/AI_OPTIMIZER.md) ā SQL optimization
|
|
1346
|
+
- [AI Prompt Enhancer](docs/AI_PROMPT.md) ā Schema/code generation
|
|
1347
|
+
- [MCP Server](docs/MCP.md) ā AI agent integration
|
|
1348
|
+
- [AI Safety Guardrails](docs/AI_SAFETY.md) ā Destructive operation protection
|
|
1349
|
+
|
|
1223
1350
|
## š Documentation
|
|
1224
1351
|
|
|
1225
1352
|
- [Migrations Guide](docs/MIGRATIONS.md)
|
|
@@ -1227,7 +1354,8 @@ outlet-convert
|
|
|
1227
1354
|
- [Relation Detection](docs/RELATIONS_DETECTION.md)
|
|
1228
1355
|
- [Quick Start Guide](docs/QUICKSTART.md)
|
|
1229
1356
|
- [Architecture](docs/ARCHITECTURE.md)
|
|
1230
|
-
- [**TypeScript (
|
|
1357
|
+
- [**TypeScript (complete)**](docs/TYPESCRIPT.md)
|
|
1358
|
+
- [**AI Integration (complete)**](docs/AI_BRIDGE.md)
|
|
1231
1359
|
|
|
1232
1360
|
## š TypeScript Support
|
|
1233
1361
|
|
package/bin/init.js
CHANGED
|
@@ -16,7 +16,129 @@ const rl = readline.createInterface({
|
|
|
16
16
|
|
|
17
17
|
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
18
18
|
|
|
19
|
+
// āāā Parse CLI flags āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
20
|
+
|
|
21
|
+
function parseInitFlags(argv) {
|
|
22
|
+
const flags = {};
|
|
23
|
+
for (let i = 0; i < argv.length; i++) {
|
|
24
|
+
const arg = argv[i];
|
|
25
|
+
if (arg === '--prompt' || arg === '-P') {
|
|
26
|
+
flags.prompt = argv[++i];
|
|
27
|
+
} else if (arg === '--driver' || arg === '-d') {
|
|
28
|
+
flags.driver = argv[++i];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return flags;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// āāā Prompt-based init (v7.0.0) āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
35
|
+
|
|
36
|
+
async function initFromPrompt(promptText, driverName) {
|
|
37
|
+
const PromptGenerator = require('../src/AI/PromptGenerator');
|
|
38
|
+
|
|
39
|
+
console.log('\nš¤ Outlet ORM ā Prompt-based Initialization\n');
|
|
40
|
+
console.log(` Prompt: "${promptText}"`);
|
|
41
|
+
|
|
42
|
+
const blueprint = PromptGenerator.parse(promptText);
|
|
43
|
+
console.log(` Domain detected: ${blueprint.domain} (score: ${blueprint.score})`);
|
|
44
|
+
console.log(` Tables: ${Object.keys(blueprint.tables).join(', ')}\n`);
|
|
45
|
+
|
|
46
|
+
// Determine the driver
|
|
47
|
+
const driver = driverName || 'sqlite';
|
|
48
|
+
const driverConfig = {
|
|
49
|
+
mysql: { package: 'mysql2', port: 3306 },
|
|
50
|
+
postgres: { package: 'pg', port: 5432 },
|
|
51
|
+
sqlite: { package: 'sqlite3', port: null }
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (!driverConfig[driver]) {
|
|
55
|
+
console.error(`ā Unknown driver: ${driver}. Use mysql, postgres, or sqlite.`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const cwd = process.cwd();
|
|
60
|
+
|
|
61
|
+
// Create directory structure
|
|
62
|
+
const directories = ['database/migrations', 'database/seeds', 'models', 'config'];
|
|
63
|
+
for (const dir of directories) {
|
|
64
|
+
const dirPath = path.join(cwd, dir);
|
|
65
|
+
if (!fs.existsSync(dirPath)) {
|
|
66
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
67
|
+
console.log(` š ${dir}/`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Generate database config
|
|
72
|
+
let config;
|
|
73
|
+
if (driver === 'sqlite') {
|
|
74
|
+
config = { driver: 'sqlite', database: './database.sqlite' };
|
|
75
|
+
} else {
|
|
76
|
+
config = {
|
|
77
|
+
driver,
|
|
78
|
+
host: 'localhost',
|
|
79
|
+
port: driverConfig[driver].port,
|
|
80
|
+
database: 'my_app',
|
|
81
|
+
user: 'root',
|
|
82
|
+
password: ''
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const configContent = `const { DatabaseConnection } = require('outlet-orm');\n\nconst db = new DatabaseConnection(${JSON.stringify(config, null, 2)});\n\nmodule.exports = db;\n`;
|
|
87
|
+
const configPath = path.join(cwd, 'database', 'config.js');
|
|
88
|
+
if (!fs.existsSync(configPath)) {
|
|
89
|
+
fs.writeFileSync(configPath, configContent);
|
|
90
|
+
console.log(' ā
database/config.js');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Generate .env
|
|
94
|
+
const envPath = path.join(cwd, '.env');
|
|
95
|
+
if (!fs.existsSync(envPath)) {
|
|
96
|
+
const envLines = [`DB_DRIVER=${config.driver}`];
|
|
97
|
+
if (driver !== 'sqlite') {
|
|
98
|
+
envLines.push(`DB_HOST=${config.host}`, `DB_PORT=${config.port}`, `DB_USER=${config.user}`, `DB_PASSWORD=${config.password}`, `DB_DATABASE=${config.database}`);
|
|
99
|
+
} else {
|
|
100
|
+
envLines.push(`DB_FILE=${config.database}`);
|
|
101
|
+
}
|
|
102
|
+
fs.writeFileSync(envPath, envLines.join('\n') + '\n');
|
|
103
|
+
console.log(' ā
.env');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Generate models
|
|
107
|
+
console.log('\nš Generating models...');
|
|
108
|
+
const modelFiles = PromptGenerator.generateModels(blueprint, path.join(cwd, 'models'));
|
|
109
|
+
for (const f of modelFiles) {
|
|
110
|
+
console.log(` ā
${path.relative(cwd, f)}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Generate migrations
|
|
114
|
+
console.log('\nš¦ Generating migrations...');
|
|
115
|
+
const migrationFiles = PromptGenerator.generateMigrations(blueprint, path.join(cwd, 'database', 'migrations'));
|
|
116
|
+
for (const f of migrationFiles) {
|
|
117
|
+
console.log(` ā
${path.relative(cwd, f)}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Generate seeder
|
|
121
|
+
console.log('\nš± Generating seeder...');
|
|
122
|
+
const seederFile = PromptGenerator.generateSeeder(blueprint, path.join(cwd, 'database', 'seeds'));
|
|
123
|
+
console.log(` ā
${path.relative(cwd, seederFile)}`);
|
|
124
|
+
|
|
125
|
+
console.log('\n⨠Project generated from prompt!\n');
|
|
126
|
+
console.log('Next steps:');
|
|
127
|
+
console.log(' 1. Review generated models in models/');
|
|
128
|
+
console.log(' 2. Review migrations in database/migrations/');
|
|
129
|
+
console.log(' 3. Run migrations: outlet-migrate migrate');
|
|
130
|
+
console.log(` 4. Install driver: npm install ${driverConfig[driver].package}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
19
133
|
async function init() {
|
|
134
|
+
// Check for --prompt flag
|
|
135
|
+
const flags = parseInitFlags(process.argv.slice(2));
|
|
136
|
+
if (flags.prompt) {
|
|
137
|
+
await initFromPrompt(flags.prompt, flags.driver);
|
|
138
|
+
rl.close();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
20
142
|
console.log('\nš Bienvenue dans l\'assistant de configuration Outlet ORM!\n');
|
|
21
143
|
|
|
22
144
|
try {
|
package/bin/mcp.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* outlet-mcp ā MCP Server CLI entry point
|
|
5
|
+
* Starts the Outlet ORM MCP server on stdio for AI agent integration.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx outlet-mcp # Start the MCP server
|
|
9
|
+
* npx outlet-mcp --project /path # Start with custom project directory
|
|
10
|
+
* npx outlet-mcp --no-safety # Disable AI safety guardrails
|
|
11
|
+
*
|
|
12
|
+
* @since 7.0.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const MCPServer = require('../src/AI/MCPServer');
|
|
16
|
+
|
|
17
|
+
// āāā Parse CLI flags āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
18
|
+
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
const options = {};
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < args.length; i++) {
|
|
23
|
+
const arg = args[i];
|
|
24
|
+
if (arg === '--project' || arg === '-p') {
|
|
25
|
+
options.projectDir = args[++i];
|
|
26
|
+
} else if (arg === '--no-safety') {
|
|
27
|
+
options.safetyGuardrails = false;
|
|
28
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
29
|
+
console.error(`
|
|
30
|
+
outlet-mcp ā Outlet ORM MCP Server
|
|
31
|
+
|
|
32
|
+
Usage:
|
|
33
|
+
outlet-mcp [options]
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--project, -p <path> Project root directory (default: cwd)
|
|
37
|
+
--no-safety Disable AI safety guardrails
|
|
38
|
+
--help, -h Show this help message
|
|
39
|
+
|
|
40
|
+
The server communicates over stdio using the Model Context Protocol (MCP).
|
|
41
|
+
It exposes tools for migrations, schema introspection, queries, seeds, and backups.
|
|
42
|
+
|
|
43
|
+
Documentation: https://github.com/omgbwa-yasse/outlet-orm/blob/main/docs/MCP.md
|
|
44
|
+
`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// āāā Start āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
50
|
+
|
|
51
|
+
const server = new MCPServer(options);
|
|
52
|
+
|
|
53
|
+
server.on('started', () => {
|
|
54
|
+
process.stderr.write('[outlet-mcp] MCP server started on stdio\n');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
server.on('initialized', () => {
|
|
58
|
+
process.stderr.write('[outlet-mcp] Client connected and initialized\n');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
server.on('close', async () => {
|
|
62
|
+
process.stderr.write('[outlet-mcp] Shutting down...\n');
|
|
63
|
+
await server.close();
|
|
64
|
+
process.exit(0);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Graceful shutdown
|
|
68
|
+
process.on('SIGINT', async () => {
|
|
69
|
+
await server.close();
|
|
70
|
+
process.exit(0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
process.on('SIGTERM', async () => {
|
|
74
|
+
await server.close();
|
|
75
|
+
process.exit(0);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
server.start();
|
package/bin/migrate.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const readline = require('readline');
|
|
9
9
|
const fs = require('fs').promises;
|
|
10
10
|
const path = require('path');
|
|
11
|
+
const AISafetyGuardrails = require('../src/AI/AISafetyGuardrails');
|
|
11
12
|
|
|
12
13
|
const rl = readline.createInterface({
|
|
13
14
|
input: process.stdin,
|
|
@@ -367,6 +368,14 @@ async function runNonInteractive(cmd, flags) {
|
|
|
367
368
|
}
|
|
368
369
|
|
|
369
370
|
case 'reset': {
|
|
371
|
+
// AI Safety Guardrails check (v7.0.0)
|
|
372
|
+
if (AISafetyGuardrails.isDestructiveCommand('reset')) {
|
|
373
|
+
const check = AISafetyGuardrails.validateDestructiveAction('reset', flags);
|
|
374
|
+
if (!check.allowed) {
|
|
375
|
+
console.error(check.message);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
370
379
|
if (flags.yes || flags.force) {
|
|
371
380
|
await manager.reset();
|
|
372
381
|
} else {
|
|
@@ -376,6 +385,14 @@ async function runNonInteractive(cmd, flags) {
|
|
|
376
385
|
}
|
|
377
386
|
|
|
378
387
|
case 'refresh': {
|
|
388
|
+
// AI Safety Guardrails check (v7.0.0)
|
|
389
|
+
if (AISafetyGuardrails.isDestructiveCommand('fresh')) {
|
|
390
|
+
const check = AISafetyGuardrails.validateDestructiveAction('refresh', flags);
|
|
391
|
+
if (!check.allowed) {
|
|
392
|
+
console.error(check.message);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
379
396
|
if (flags.yes || flags.force) {
|
|
380
397
|
await manager.refresh();
|
|
381
398
|
} else {
|
|
@@ -385,6 +402,14 @@ async function runNonInteractive(cmd, flags) {
|
|
|
385
402
|
}
|
|
386
403
|
|
|
387
404
|
case 'fresh': {
|
|
405
|
+
// AI Safety Guardrails check (v7.0.0)
|
|
406
|
+
if (AISafetyGuardrails.isDestructiveCommand('fresh')) {
|
|
407
|
+
const check = AISafetyGuardrails.validateDestructiveAction('fresh', flags);
|
|
408
|
+
if (!check.allowed) {
|
|
409
|
+
console.error(check.message);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
388
413
|
if (flags.yes || flags.force) {
|
|
389
414
|
await manager.fresh();
|
|
390
415
|
} else {
|