@m2015agg/supabase-skill 0.1.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 (50) hide show
  1. package/README.md +383 -0
  2. package/dist/commands/columns.d.ts +2 -0
  3. package/dist/commands/columns.js +121 -0
  4. package/dist/commands/columns.js.map +1 -0
  5. package/dist/commands/context.d.ts +2 -0
  6. package/dist/commands/context.js +236 -0
  7. package/dist/commands/context.js.map +1 -0
  8. package/dist/commands/cron.d.ts +2 -0
  9. package/dist/commands/cron.js +116 -0
  10. package/dist/commands/cron.js.map +1 -0
  11. package/dist/commands/docs.d.ts +4 -0
  12. package/dist/commands/docs.js +182 -0
  13. package/dist/commands/docs.js.map +1 -0
  14. package/dist/commands/envs.d.ts +2 -0
  15. package/dist/commands/envs.js +22 -0
  16. package/dist/commands/envs.js.map +1 -0
  17. package/dist/commands/init.d.ts +2 -0
  18. package/dist/commands/init.js +85 -0
  19. package/dist/commands/init.js.map +1 -0
  20. package/dist/commands/install.d.ts +2 -0
  21. package/dist/commands/install.js +129 -0
  22. package/dist/commands/install.js.map +1 -0
  23. package/dist/commands/search.d.ts +2 -0
  24. package/dist/commands/search.js +102 -0
  25. package/dist/commands/search.js.map +1 -0
  26. package/dist/commands/snapshot.d.ts +2 -0
  27. package/dist/commands/snapshot.js +316 -0
  28. package/dist/commands/snapshot.js.map +1 -0
  29. package/dist/commands/table.d.ts +2 -0
  30. package/dist/commands/table.js +169 -0
  31. package/dist/commands/table.js.map +1 -0
  32. package/dist/commands/uninstall.d.ts +2 -0
  33. package/dist/commands/uninstall.js +30 -0
  34. package/dist/commands/uninstall.js.map +1 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +31 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/util/claude-md.d.ts +3 -0
  39. package/dist/util/claude-md.js +48 -0
  40. package/dist/util/claude-md.js.map +1 -0
  41. package/dist/util/config.d.ts +15 -0
  42. package/dist/util/config.js +37 -0
  43. package/dist/util/config.js.map +1 -0
  44. package/dist/util/db.d.ts +85 -0
  45. package/dist/util/db.js +237 -0
  46. package/dist/util/db.js.map +1 -0
  47. package/dist/util/detect.d.ts +13 -0
  48. package/dist/util/detect.js +34 -0
  49. package/dist/util/detect.js.map +1 -0
  50. package/package.json +44 -0
@@ -0,0 +1,48 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ const MARKER_START = "<!-- supabase-skill:start -->";
4
+ const MARKER_END = "<!-- supabase-skill:end -->";
5
+ export function getMarkedSnippet(content) {
6
+ return `${MARKER_START}\n${content}\n${MARKER_END}`;
7
+ }
8
+ export function upsertSection(filePath, content) {
9
+ const snippet = getMarkedSnippet(content);
10
+ const dir = dirname(filePath);
11
+ if (!existsSync(dir))
12
+ mkdirSync(dir, { recursive: true });
13
+ if (!existsSync(filePath)) {
14
+ writeFileSync(filePath, snippet + "\n");
15
+ return "created";
16
+ }
17
+ const existing = readFileSync(filePath, "utf-8");
18
+ const startIdx = existing.indexOf(MARKER_START);
19
+ const endIdx = existing.indexOf(MARKER_END);
20
+ if (startIdx !== -1 && endIdx !== -1) {
21
+ const currentSection = existing.slice(startIdx, endIdx + MARKER_END.length);
22
+ if (currentSection === snippet)
23
+ return "unchanged";
24
+ const updated = existing.slice(0, startIdx) + snippet + existing.slice(endIdx + MARKER_END.length);
25
+ writeFileSync(filePath, updated);
26
+ return "updated";
27
+ }
28
+ // No markers found — append
29
+ const separator = existing.endsWith("\n") ? "\n" : "\n\n";
30
+ writeFileSync(filePath, existing + separator + snippet + "\n");
31
+ return "updated";
32
+ }
33
+ export function removeSection(filePath) {
34
+ if (!existsSync(filePath))
35
+ return "not_found";
36
+ const content = readFileSync(filePath, "utf-8");
37
+ const startIdx = content.indexOf(MARKER_START);
38
+ const endIdx = content.indexOf(MARKER_END);
39
+ if (startIdx === -1 || endIdx === -1)
40
+ return "not_found";
41
+ let updated = content.slice(0, startIdx) + content.slice(endIdx + MARKER_END.length);
42
+ updated = updated.replace(/\n{3,}/g, "\n\n").trim();
43
+ if (updated)
44
+ updated += "\n";
45
+ writeFileSync(filePath, updated);
46
+ return "removed";
47
+ }
48
+ //# sourceMappingURL=claude-md.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/util/claude-md.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface Environment {
2
+ ref: string;
3
+ name: string;
4
+ }
5
+ export interface SkillConfig {
6
+ environments: Record<string, Environment>;
7
+ defaultEnv: string;
8
+ safetyRules: {
9
+ prodRequiresApproval: boolean;
10
+ alwaysSpecifyRef: boolean;
11
+ };
12
+ }
13
+ export declare function readConfig(): SkillConfig | null;
14
+ export declare function writeConfig(config: SkillConfig): void;
15
+ export declare function getDefaultConfig(): SkillConfig;
@@ -0,0 +1,37 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ function getConfigDir() {
5
+ return join(homedir(), ".config", "supabase-skill");
6
+ }
7
+ function getConfigPath() {
8
+ return join(getConfigDir(), "config.json");
9
+ }
10
+ export function readConfig() {
11
+ const path = getConfigPath();
12
+ if (!existsSync(path))
13
+ return null;
14
+ try {
15
+ return JSON.parse(readFileSync(path, "utf-8"));
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ export function writeConfig(config) {
22
+ const dir = getConfigDir();
23
+ if (!existsSync(dir))
24
+ mkdirSync(dir, { recursive: true });
25
+ writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + "\n");
26
+ }
27
+ export function getDefaultConfig() {
28
+ return {
29
+ environments: {},
30
+ defaultEnv: "stage",
31
+ safetyRules: {
32
+ prodRequiresApproval: true,
33
+ alwaysSpecifyRef: true,
34
+ },
35
+ };
36
+ }
37
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/util/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAgBlC,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAgB,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,OAAO;QACnB,WAAW,EAAE;YACX,oBAAoB,EAAE,IAAI;YAC1B,gBAAgB,EAAE,IAAI;SACvB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,85 @@
1
+ import Database from "better-sqlite3";
2
+ export declare function openDb(schemaDir: string): Database.Database;
3
+ export declare function hasDb(schemaDir: string): boolean;
4
+ export declare function initSchema(db: Database.Database): void;
5
+ export declare function clearData(db: Database.Database): void;
6
+ export interface TableRow {
7
+ name: string;
8
+ column_count: number;
9
+ pk_count: number;
10
+ fk_count: number;
11
+ is_view: boolean;
12
+ }
13
+ export interface ColumnRow {
14
+ table_name: string;
15
+ name: string;
16
+ type: string | null;
17
+ nullable: boolean;
18
+ default_value: string | null;
19
+ is_pk: boolean;
20
+ fk_table: string | null;
21
+ fk_column: string | null;
22
+ description: string | null;
23
+ }
24
+ export interface RelRow {
25
+ from_table: string;
26
+ from_column: string;
27
+ to_table: string;
28
+ to_column: string;
29
+ }
30
+ export interface FuncRow {
31
+ name: string;
32
+ params: string;
33
+ description: string | null;
34
+ }
35
+ export declare function insertAll(db: Database.Database, tables: TableRow[], columns: ColumnRow[], rels: RelRow[], funcs: FuncRow[]): void;
36
+ export interface FtsResult {
37
+ name: string;
38
+ type: string;
39
+ parent: string;
40
+ detail: string;
41
+ description: string;
42
+ rank: number;
43
+ }
44
+ export declare function searchFTS(db: Database.Database, query: string): FtsResult[];
45
+ export interface ColumnQueryResult {
46
+ table_name: string;
47
+ name: string;
48
+ type: string;
49
+ nullable: number;
50
+ default_value: string | null;
51
+ is_pk: number;
52
+ fk_table: string | null;
53
+ fk_column: string | null;
54
+ description: string | null;
55
+ }
56
+ export declare function queryColumns(db: Database.Database, opts: {
57
+ name?: string;
58
+ type?: string;
59
+ fk?: boolean;
60
+ pk?: boolean;
61
+ nullable?: boolean;
62
+ notNull?: boolean;
63
+ hasDefault?: boolean;
64
+ table?: string;
65
+ }): ColumnQueryResult[];
66
+ export interface RelatedTable {
67
+ table_name: string;
68
+ direction: string;
69
+ from_column: string;
70
+ to_column: string;
71
+ depth: number;
72
+ }
73
+ export declare function getRelatedTables(db: Database.Database, tableName: string, maxDepth: number): RelatedTable[];
74
+ export declare function getTableColumns(db: Database.Database, tableName: string): ColumnQueryResult[];
75
+ export declare function getTableInfo(db: Database.Database, tableName: string): TableRow | undefined;
76
+ export declare function getAllTableNames(db: Database.Database): string[];
77
+ export declare function findMatchingFunctions(db: Database.Database, query: string): Array<{
78
+ name: string;
79
+ params: string;
80
+ description: string | null;
81
+ }>;
82
+ export declare function getRelationshipsFor(db: Database.Database, tableName: string): {
83
+ outgoing: RelRow[];
84
+ incoming: RelRow[];
85
+ };
@@ -0,0 +1,237 @@
1
+ import Database from "better-sqlite3";
2
+ import { join } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ const DB_FILENAME = "schema.db";
5
+ // ─── Schema Creation ───
6
+ const SCHEMA_SQL = `
7
+ CREATE TABLE IF NOT EXISTS tables (
8
+ name TEXT PRIMARY KEY,
9
+ column_count INTEGER,
10
+ pk_count INTEGER,
11
+ fk_count INTEGER,
12
+ is_view BOOLEAN DEFAULT FALSE
13
+ );
14
+
15
+ CREATE TABLE IF NOT EXISTS columns (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ table_name TEXT NOT NULL,
18
+ name TEXT NOT NULL,
19
+ type TEXT,
20
+ nullable BOOLEAN,
21
+ default_value TEXT,
22
+ is_pk BOOLEAN DEFAULT FALSE,
23
+ fk_table TEXT,
24
+ fk_column TEXT,
25
+ description TEXT
26
+ );
27
+
28
+ CREATE TABLE IF NOT EXISTS relationships (
29
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
30
+ from_table TEXT NOT NULL,
31
+ from_column TEXT NOT NULL,
32
+ to_table TEXT NOT NULL,
33
+ to_column TEXT NOT NULL
34
+ );
35
+
36
+ CREATE TABLE IF NOT EXISTS functions (
37
+ name TEXT PRIMARY KEY,
38
+ params TEXT,
39
+ description TEXT
40
+ );
41
+
42
+ CREATE VIRTUAL TABLE IF NOT EXISTS schema_fts USING fts5(
43
+ name,
44
+ type,
45
+ parent,
46
+ detail,
47
+ description,
48
+ tokenize='porter unicode61'
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_columns_table ON columns(table_name);
52
+ CREATE INDEX IF NOT EXISTS idx_columns_type ON columns(type);
53
+ CREATE INDEX IF NOT EXISTS idx_columns_fk ON columns(fk_table) WHERE fk_table IS NOT NULL;
54
+ CREATE INDEX IF NOT EXISTS idx_columns_pk ON columns(is_pk) WHERE is_pk = TRUE;
55
+ CREATE INDEX IF NOT EXISTS idx_rels_from ON relationships(from_table);
56
+ CREATE INDEX IF NOT EXISTS idx_rels_to ON relationships(to_table);
57
+ `;
58
+ // ─── Open / Init ───
59
+ export function openDb(schemaDir) {
60
+ const dbPath = join(schemaDir, DB_FILENAME);
61
+ const db = new Database(dbPath);
62
+ db.pragma("journal_mode = WAL");
63
+ db.pragma("foreign_keys = OFF");
64
+ return db;
65
+ }
66
+ export function hasDb(schemaDir) {
67
+ return existsSync(join(schemaDir, DB_FILENAME));
68
+ }
69
+ export function initSchema(db) {
70
+ db.exec(SCHEMA_SQL);
71
+ }
72
+ export function clearData(db) {
73
+ db.exec("DELETE FROM schema_fts");
74
+ db.exec("DELETE FROM columns");
75
+ db.exec("DELETE FROM relationships");
76
+ db.exec("DELETE FROM functions");
77
+ db.exec("DELETE FROM tables");
78
+ }
79
+ export function insertAll(db, tables, columns, rels, funcs) {
80
+ const insertTable = db.prepare("INSERT OR REPLACE INTO tables (name, column_count, pk_count, fk_count, is_view) VALUES (?, ?, ?, ?, ?)");
81
+ const insertColumn = db.prepare("INSERT INTO columns (table_name, name, type, nullable, default_value, is_pk, fk_table, fk_column, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
82
+ const insertRel = db.prepare("INSERT INTO relationships (from_table, from_column, to_table, to_column) VALUES (?, ?, ?, ?)");
83
+ const insertFunc = db.prepare("INSERT OR REPLACE INTO functions (name, params, description) VALUES (?, ?, ?)");
84
+ const insertFts = db.prepare("INSERT INTO schema_fts (name, type, parent, detail, description) VALUES (?, ?, ?, ?, ?)");
85
+ // Coerce any value to SQLite-safe (no booleans, no undefined)
86
+ function safe(v) {
87
+ if (v === undefined || v === null)
88
+ return null;
89
+ if (typeof v === "boolean")
90
+ return v ? 1 : 0;
91
+ if (typeof v === "number")
92
+ return v;
93
+ return String(v);
94
+ }
95
+ const tx = db.transaction(() => {
96
+ for (const t of tables) {
97
+ insertTable.run(safe(t.name), safe(t.column_count), safe(t.pk_count), safe(t.fk_count), safe(t.is_view));
98
+ insertFts.run(safe(t.name), "table", "", `${t.column_count} columns ${t.pk_count} PK ${t.fk_count} FK`, "");
99
+ }
100
+ for (const c of columns) {
101
+ insertColumn.run(safe(c.table_name), safe(c.name), safe(c.type), safe(c.nullable), safe(c.default_value), safe(c.is_pk), safe(c.fk_table), safe(c.fk_column), safe(c.description));
102
+ const detail = [c.type, c.fk_table ? `FK → ${c.fk_table}.${c.fk_column}` : ""].filter(Boolean).join(" ");
103
+ insertFts.run(safe(c.name), "column", safe(c.table_name), detail, safe(c.description) ?? "");
104
+ }
105
+ for (const r of rels) {
106
+ insertRel.run(safe(r.from_table), safe(r.from_column), safe(r.to_table), safe(r.to_column));
107
+ }
108
+ for (const f of funcs) {
109
+ insertFunc.run(safe(f.name), safe(f.params), safe(f.description));
110
+ insertFts.run(safe(f.name), "function", "", safe(f.params) ?? "", safe(f.description) ?? "");
111
+ }
112
+ });
113
+ tx();
114
+ }
115
+ export function searchFTS(db, query) {
116
+ // Escape special FTS5 characters and add prefix matching
117
+ const safeQuery = query.replace(/['"]/g, "").trim();
118
+ if (!safeQuery)
119
+ return [];
120
+ try {
121
+ // Try prefix match first (more intuitive for partial names)
122
+ const results = db.prepare(`
123
+ SELECT name, type, parent, detail, description, rank
124
+ FROM schema_fts
125
+ WHERE schema_fts MATCH ?
126
+ ORDER BY rank
127
+ LIMIT 100
128
+ `).all(`"${safeQuery}"*`);
129
+ return results;
130
+ }
131
+ catch {
132
+ // Fallback to simple LIKE if FTS5 match fails
133
+ return db.prepare(`
134
+ SELECT name, type, parent, detail, description, 0 as rank
135
+ FROM schema_fts
136
+ WHERE name LIKE ? OR parent LIKE ? OR detail LIKE ? OR description LIKE ?
137
+ ORDER BY type, name
138
+ LIMIT 100
139
+ `).all(`%${safeQuery}%`, `%${safeQuery}%`, `%${safeQuery}%`, `%${safeQuery}%`);
140
+ }
141
+ }
142
+ export function queryColumns(db, opts) {
143
+ const conditions = [];
144
+ const params = [];
145
+ if (opts.name) {
146
+ conditions.push("c.name LIKE ?");
147
+ params.push(`%${opts.name}%`);
148
+ }
149
+ if (opts.type) {
150
+ conditions.push("c.type LIKE ?");
151
+ params.push(`%${opts.type}%`);
152
+ }
153
+ if (opts.fk) {
154
+ conditions.push("c.fk_table IS NOT NULL");
155
+ }
156
+ if (opts.pk) {
157
+ conditions.push("c.is_pk = 1");
158
+ }
159
+ if (opts.nullable) {
160
+ conditions.push("c.nullable = 1");
161
+ }
162
+ if (opts.notNull) {
163
+ conditions.push("c.nullable = 0");
164
+ }
165
+ if (opts.hasDefault) {
166
+ conditions.push("c.default_value IS NOT NULL AND c.default_value != ''");
167
+ }
168
+ if (opts.table) {
169
+ conditions.push("c.table_name LIKE ?");
170
+ params.push(`%${opts.table}%`);
171
+ }
172
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
173
+ return db.prepare(`
174
+ SELECT c.table_name, c.name, c.type, c.nullable, c.default_value,
175
+ c.is_pk, c.fk_table, c.fk_column, c.description
176
+ FROM columns c
177
+ ${where}
178
+ ORDER BY c.table_name, c.name
179
+ `).all(...params);
180
+ }
181
+ export function getRelatedTables(db, tableName, maxDepth) {
182
+ // Outgoing (this table references)
183
+ const outgoing = db.prepare(`
184
+ WITH RECURSIVE refs(tbl, from_col, to_col, depth) AS (
185
+ SELECT to_table, from_column, to_column, 1
186
+ FROM relationships WHERE from_table = ?
187
+ UNION ALL
188
+ SELECT r.to_table, r.from_column, r.to_column, refs.depth + 1
189
+ FROM relationships r
190
+ JOIN refs ON r.from_table = refs.tbl
191
+ WHERE refs.depth < ?
192
+ )
193
+ SELECT DISTINCT tbl as table_name, 'references' as direction, from_col as from_column, to_col as to_column, depth
194
+ FROM refs
195
+ `).all(tableName, maxDepth);
196
+ // Incoming (referenced by)
197
+ const incoming = db.prepare(`
198
+ WITH RECURSIVE refs(tbl, from_col, to_col, depth) AS (
199
+ SELECT from_table, from_column, to_column, 1
200
+ FROM relationships WHERE to_table = ?
201
+ UNION ALL
202
+ SELECT r.from_table, r.from_column, r.to_column, refs.depth + 1
203
+ FROM relationships r
204
+ JOIN refs ON r.to_table = refs.tbl
205
+ WHERE refs.depth < ?
206
+ )
207
+ SELECT DISTINCT tbl as table_name, 'referenced by' as direction, from_col as from_column, to_col as to_column, depth
208
+ FROM refs
209
+ `).all(tableName, maxDepth);
210
+ return [...outgoing, ...incoming];
211
+ }
212
+ export function getTableColumns(db, tableName) {
213
+ return db.prepare(`
214
+ SELECT table_name, name, type, nullable, default_value, is_pk, fk_table, fk_column, description
215
+ FROM columns WHERE table_name = ?
216
+ ORDER BY id
217
+ `).all(tableName);
218
+ }
219
+ export function getTableInfo(db, tableName) {
220
+ return db.prepare("SELECT * FROM tables WHERE name = ?").get(tableName);
221
+ }
222
+ export function getAllTableNames(db) {
223
+ return db.prepare("SELECT name FROM tables ORDER BY name").all().map((r) => r.name);
224
+ }
225
+ export function findMatchingFunctions(db, query) {
226
+ return db.prepare(`
227
+ SELECT name, params, description FROM functions
228
+ WHERE name LIKE ?
229
+ ORDER BY name
230
+ `).all(`%${query}%`);
231
+ }
232
+ export function getRelationshipsFor(db, tableName) {
233
+ const outgoing = db.prepare("SELECT from_table, from_column, to_table, to_column FROM relationships WHERE from_table = ?").all(tableName);
234
+ const incoming = db.prepare("SELECT from_table, from_column, to_table, to_column FROM relationships WHERE to_table = ?").all(tableName);
235
+ return { outgoing, incoming };
236
+ }
237
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/util/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface SupabaseProject {
2
+ id: string;
3
+ name: string;
4
+ organization_id: string;
5
+ region: string;
6
+ created_at: string;
7
+ }
8
+ export declare function isSupabaseCLIInstalled(): {
9
+ installed: boolean;
10
+ version: string;
11
+ };
12
+ export declare function isLoggedIn(): boolean;
13
+ export declare function listProjects(): SupabaseProject[];
@@ -0,0 +1,34 @@
1
+ import { execSync } from "node:child_process";
2
+ export function isSupabaseCLIInstalled() {
3
+ try {
4
+ const output = execSync("supabase --version 2>&1", { encoding: "utf-8" }).trim();
5
+ const match = output.match(/(\d+\.\d+\.\d+)/);
6
+ return { installed: true, version: match ? match[1] : output };
7
+ }
8
+ catch {
9
+ return { installed: false, version: "" };
10
+ }
11
+ }
12
+ export function isLoggedIn() {
13
+ try {
14
+ execSync("supabase projects list -o json 2>&1", { encoding: "utf-8", timeout: 15000 });
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ export function listProjects() {
22
+ try {
23
+ const output = execSync("supabase projects list -o json 2>&1", {
24
+ encoding: "utf-8",
25
+ timeout: 15000,
26
+ });
27
+ const parsed = JSON.parse(output);
28
+ return Array.isArray(parsed) ? parsed : [];
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
34
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/util/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAU9C,MAAM,UAAU,sBAAsB;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC9C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,QAAQ,CAAC,qCAAqC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,qCAAqC,EAAE;YAC7D,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@m2015agg/supabase-skill",
3
+ "version": "0.1.0",
4
+ "description": "Supabase CLI skill for AI agents. Installs comprehensive CLI instructions into CLAUDE.md, AGENTS.md, or .cursorrules with multi-environment support.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "supabase-skill": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "link": "npm run build && npm link",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "supabase",
20
+ "cli",
21
+ "ai",
22
+ "claude",
23
+ "agent",
24
+ "skill",
25
+ "llm",
26
+ "mcp-alternative"
27
+ ],
28
+ "author": "m2015agg <matthgreen2015@gmail.com>",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "better-sqlite3": "^12.8.0",
32
+ "commander": "^13.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/better-sqlite3": "^7.6.13",
36
+ "@types/node": "^25.5.0",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^3.0.0"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md"
43
+ ]
44
+ }