chore(scripts): add scratch maintenance utilities and ai workspace rules

Add one-off database inspection and cleanup scripts under
`scripts/scratch/` for local debugging and maintenance work.

Document root cleanliness and file placement expectations for AI
assistants in `GEMINI.md` to keep temporary scripts and tests out of
the project root.
This commit is contained in:
diegosouzapw
2026-04-16 13:32:12 -03:00
parent 438f25214c
commit adf59ddce7
8 changed files with 102 additions and 0 deletions

15
GEMINI.md Normal file
View File

@@ -0,0 +1,15 @@
# Security and Cleanliness Rules for AI Assistants
## 1. File Placement & Organization
- **Test Files**: ALL unit tests, integration tests, ecosystem tests, or Vitest files MUST strictly be placed within the `tests/` directory (e.g., `tests/unit/`, `tests/integration/`). NEVER create test files in the project root (`/`).
- **Scripts and Utilities**: ALL maintenance, debugging, generation, or experimental scripts (`.cjs`, `.mjs`, `.js`, `.ts`) MUST be placed strictly inside the `scripts/` directory or `scripts/scratch/` for temporary one-offs. NEVER dump loose scripts in the project root (`/`).
**The Project Root MUST ONLY CONTAIN:**
- Configuration files (`vitest.config.ts`, `next.config.mjs`, `eslint.config.mjs`, etc.)
- Dependency files (`package.json`, `package-lock.json`)
- Documentation files (`README.md`, `CHANGELOG.md`, `AGENTS.md`)
- CI/CD files and ignore definitions (`.gitignore`, `.dockerignore`)
When creating _any_ validation tests or one-off logic scripts, default to using `scripts/scratch/` or the `tests/unit/` directories according to your goals. Do not pollute the `/` root context.

View File

@@ -0,0 +1,7 @@
const Database = require('better-sqlite3');
const db = new Database(process.env.HOME + '/.omniroute/storage.sqlite');
console.log("Deleting iflow connections...");
const stmt = db.prepare("DELETE FROM provider_connections WHERE provider = 'iflow'");
const info = stmt.run();
console.log(`Deleted ${info.changes} rows.`);

View File

@@ -0,0 +1,23 @@
import {
APIKEY_PROVIDERS,
SEARCH_PROVIDERS,
AUDIO_ONLY_PROVIDERS,
WEB_COOKIE_PROVIDERS,
} from "./src/shared/constants/providers";
console.log("SEARCH_PROVIDERS", !!SEARCH_PROVIDERS, Object.keys(SEARCH_PROVIDERS || {}));
console.log("AUDIO_ONLY", !!AUDIO_ONLY_PROVIDERS);
console.log("WEB_COOKIE", !!WEB_COOKIE_PROVIDERS);
// Determine auth type group for a provider id
function getAuthGroup(providerId: string) {
if (WEB_COOKIE_PROVIDERS && WEB_COOKIE_PROVIDERS[providerId]) return "web-cookie";
if (SEARCH_PROVIDERS && SEARCH_PROVIDERS[providerId]) return "search";
if (AUDIO_ONLY_PROVIDERS && AUDIO_ONLY_PROVIDERS[providerId]) return "audio";
if (APIKEY_PROVIDERS && APIKEY_PROVIDERS[providerId]) return "apikey";
return "apikey";
}
console.log("grok-web returns:", getAuthGroup("grok-web"));
console.log("perplexity-search returns:", getAuthGroup("perplexity-search"));
console.log("openai returns:", getAuthGroup("openai"));

View File

@@ -0,0 +1,21 @@
import {
APIKEY_PROVIDERS,
SEARCH_PROVIDERS,
AUDIO_ONLY_PROVIDERS,
WEB_COOKIE_PROVIDERS,
} from "./src/shared/constants/providers.ts";
const apiKeys = Object.keys(APIKEY_PROVIDERS);
console.log("Searching overlap in APIKEY_PROVIDERS:");
console.log(
"Search overlap:",
Object.keys(SEARCH_PROVIDERS).filter((k) => apiKeys.includes(k))
);
console.log(
"Audio overlap:",
Object.keys(AUDIO_ONLY_PROVIDERS).filter((k) => apiKeys.includes(k))
);
console.log(
"Web Cookie overlap:",
Object.keys(WEB_COOKIE_PROVIDERS).filter((k) => apiKeys.includes(k))
);

View File

@@ -0,0 +1,8 @@
import { APIKEY_PROVIDERS, SEARCH_PROVIDERS } from "./src/shared/constants/providers.ts";
const apiKeys = Object.keys(APIKEY_PROVIDERS);
console.log(
"Overlap:",
Object.keys(SEARCH_PROVIDERS).filter((k) => apiKeys.includes(k))
);
console.log("Is perplexity-search in APIKEY?", "perplexity-search" in APIKEY_PROVIDERS);

View File

@@ -0,0 +1,18 @@
const Database = require('better-sqlite3');
const db = new Database(process.env.HOME + '/.omniroute/storage.sqlite');
const providers = db.prepare("SELECT * FROM provider_connections").all();
console.log("=== provider_connections ===");
console.log(providers.filter(p => JSON.stringify(p).toLowerCase().includes('iflow')));
const combos = db.prepare("SELECT * FROM combos").all();
console.log("=== combos ===");
console.log(combos.filter(c => JSON.stringify(c).toLowerCase().includes('iflow')));
const settings = db.prepare("SELECT * FROM settings").all();
console.log("=== settings ===");
console.log(settings.filter(s => JSON.stringify(s).toLowerCase().includes('iflow')));
const apiKeys = db.prepare("SELECT * FROM api_keys").all();
console.log("=== api_keys ===");
console.log(apiKeys.filter(k => JSON.stringify(k).toLowerCase().includes('iflow')));

View File

@@ -0,0 +1,10 @@
const Database = require("better-sqlite3");
const db = new Database(process.env.HOME + "/.omniroute/storage.sqlite");
console.log("=== provider_connections containing iflow ===");
console.log(
db
.prepare(
"SELECT id, provider_id, alias, account_id FROM provider_connections WHERE provider_id LIKE '%iflow%' OR alias LIKE '%iflow%' OR account_id LIKE '%iflow%'"
)
.all()
);