@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.
- package/README.md +383 -0
- package/dist/commands/columns.d.ts +2 -0
- package/dist/commands/columns.js +121 -0
- package/dist/commands/columns.js.map +1 -0
- package/dist/commands/context.d.ts +2 -0
- package/dist/commands/context.js +236 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/cron.d.ts +2 -0
- package/dist/commands/cron.js +116 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.js +182 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/envs.d.ts +2 -0
- package/dist/commands/envs.js +22 -0
- package/dist/commands/envs.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +85 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.js +129 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +102 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/snapshot.d.ts +2 -0
- package/dist/commands/snapshot.js +316 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/commands/table.d.ts +2 -0
- package/dist/commands/table.js +169 -0
- package/dist/commands/table.js.map +1 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.js +30 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/util/claude-md.d.ts +3 -0
- package/dist/util/claude-md.js +48 -0
- package/dist/util/claude-md.js.map +1 -0
- package/dist/util/config.d.ts +15 -0
- package/dist/util/config.js +37 -0
- package/dist/util/config.js.map +1 -0
- package/dist/util/db.d.ts +85 -0
- package/dist/util/db.js +237 -0
- package/dist/util/db.js.map +1 -0
- package/dist/util/detect.d.ts +13 -0
- package/dist/util/detect.js +34 -0
- package/dist/util/detect.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
4
|
+
import { hasDb, openDb, getTableColumns, getRelatedTables, findMatchingFunctions, getAllTableNames, } from "../util/db.js";
|
|
5
|
+
function write(msg) {
|
|
6
|
+
process.stdout.write(msg);
|
|
7
|
+
}
|
|
8
|
+
function parseTableFile(filePath) {
|
|
9
|
+
const content = readFileSync(filePath, "utf-8");
|
|
10
|
+
const columns = [];
|
|
11
|
+
const notes = [];
|
|
12
|
+
let inNotes = false;
|
|
13
|
+
for (const line of content.split("\n")) {
|
|
14
|
+
if (line.startsWith("## Notes")) {
|
|
15
|
+
inNotes = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (inNotes && line.startsWith("- ")) {
|
|
19
|
+
notes.push(line);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (line.startsWith("|") && !line.startsWith("| Column") && !line.startsWith("|---")) {
|
|
23
|
+
const cols = line.split("|").slice(1, -1).map((c) => c.trim());
|
|
24
|
+
if (cols.length >= 5) {
|
|
25
|
+
columns.push({
|
|
26
|
+
name: cols[0].replace(/\s*\*\*PK\*\*/, ""),
|
|
27
|
+
type: cols[1], nullable: cols[2], defaultVal: cols[3],
|
|
28
|
+
fk: cols[4], isPk: cols[0].includes("**PK**"),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { columns, notes };
|
|
34
|
+
}
|
|
35
|
+
// ─── SQLite Path ───
|
|
36
|
+
function renderColumnsFromDb(cols) {
|
|
37
|
+
const pkCount = cols.filter((c) => c.is_pk).length;
|
|
38
|
+
const fkCount = cols.filter((c) => c.fk_table).length;
|
|
39
|
+
write(`${cols.length} columns | ${pkCount} PK | ${fkCount} FK\n\n`);
|
|
40
|
+
write("| Column | Type | Nullable | Default | FK |\n");
|
|
41
|
+
write("|--------|------|----------|---------|----|");
|
|
42
|
+
for (const col of cols) {
|
|
43
|
+
const pk = col.is_pk ? " **PK**" : "";
|
|
44
|
+
const nullable = col.nullable ? "nullable" : "NOT NULL";
|
|
45
|
+
const fk = col.fk_table ? `→ ${col.fk_table}.${col.fk_column}` : "";
|
|
46
|
+
write(`\n| ${col.name}${pk} | ${col.type || "unknown"} | ${nullable} | ${col.default_value || ""} | ${fk} |`);
|
|
47
|
+
}
|
|
48
|
+
write("\n\n");
|
|
49
|
+
const notes = cols.filter((c) => c.description);
|
|
50
|
+
if (notes.length > 0) {
|
|
51
|
+
for (const col of notes) {
|
|
52
|
+
write(`- **${col.name}**: ${col.description}\n`);
|
|
53
|
+
}
|
|
54
|
+
write("\n");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function runSqlite(schemaDir, query, depth, jsonMode) {
|
|
58
|
+
const db = openDb(schemaDir);
|
|
59
|
+
const q = query.toLowerCase();
|
|
60
|
+
const allTables = getAllTableNames(db);
|
|
61
|
+
let entryTables = allTables.filter((t) => t === q);
|
|
62
|
+
if (entryTables.length === 0)
|
|
63
|
+
entryTables = allTables.filter((t) => t.includes(q));
|
|
64
|
+
if (entryTables.length === 0) {
|
|
65
|
+
// Search by column name
|
|
66
|
+
const colMatches = db.prepare("SELECT DISTINCT table_name FROM columns WHERE name LIKE ?").all(`%${q}%`);
|
|
67
|
+
entryTables = colMatches.map((r) => r.table_name);
|
|
68
|
+
}
|
|
69
|
+
const matchingFuncs = findMatchingFunctions(db, q);
|
|
70
|
+
if (jsonMode) {
|
|
71
|
+
const result = entryTables.slice(0, 5).map((table) => ({
|
|
72
|
+
name: table,
|
|
73
|
+
columns: getTableColumns(db, table),
|
|
74
|
+
related: getRelatedTables(db, table, depth),
|
|
75
|
+
}));
|
|
76
|
+
db.close();
|
|
77
|
+
write(JSON.stringify({ entryTables: result, functions: matchingFuncs }, null, 2) + "\n");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (entryTables.length === 0 && matchingFuncs.length === 0) {
|
|
81
|
+
db.close();
|
|
82
|
+
write(`No tables or columns match "${query}"\n`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
write(`\n# Context for "${query}"\n\n`);
|
|
86
|
+
for (const table of entryTables.slice(0, 5)) {
|
|
87
|
+
const cols = getTableColumns(db, table);
|
|
88
|
+
const related = getRelatedTables(db, table, depth);
|
|
89
|
+
write(`## ${table}\n`);
|
|
90
|
+
renderColumnsFromDb(cols);
|
|
91
|
+
const refs = related.filter((r) => r.direction === "references");
|
|
92
|
+
const refBy = related.filter((r) => r.direction === "referenced by");
|
|
93
|
+
if (refs.length > 0 || refBy.length > 0) {
|
|
94
|
+
write("### Related Tables\n\n");
|
|
95
|
+
if (refs.length > 0) {
|
|
96
|
+
write("**References (this table points to):**\n");
|
|
97
|
+
for (const r of refs)
|
|
98
|
+
write(` → ${r.table_name} via ${r.from_column} → ${r.table_name}.${r.to_column}\n`);
|
|
99
|
+
write("\n");
|
|
100
|
+
}
|
|
101
|
+
if (refBy.length > 0) {
|
|
102
|
+
write("**Referenced by (points to this table):**\n");
|
|
103
|
+
for (const r of refBy)
|
|
104
|
+
write(` ← ${r.table_name} via ${r.table_name}.${r.from_column} → ${r.to_column}\n`);
|
|
105
|
+
write("\n");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
write("---\n\n");
|
|
109
|
+
}
|
|
110
|
+
if (entryTables.length > 5)
|
|
111
|
+
write(`... and ${entryTables.length - 5} more matching tables\n\n`);
|
|
112
|
+
if (matchingFuncs.length > 0) {
|
|
113
|
+
write("## Related Functions\n\n");
|
|
114
|
+
for (const func of matchingFuncs) {
|
|
115
|
+
const params = JSON.parse(func.params || "[]");
|
|
116
|
+
const paramStr = params.length > 0 ? `(${params.map((p) => `${p.name}`).join(", ")})` : "()";
|
|
117
|
+
write(`- \`${func.name}${paramStr}\`\n`);
|
|
118
|
+
}
|
|
119
|
+
write("\n");
|
|
120
|
+
}
|
|
121
|
+
db.close();
|
|
122
|
+
}
|
|
123
|
+
// ─── Markdown Fallback Path ───
|
|
124
|
+
function runMarkdown(schemaDir, query, depth, jsonMode) {
|
|
125
|
+
const tablesDir = join(schemaDir, "tables");
|
|
126
|
+
const allTables = readdirSync(tablesDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
127
|
+
const q = query.toLowerCase();
|
|
128
|
+
let entryTables = allTables.filter((t) => t === q);
|
|
129
|
+
if (entryTables.length === 0)
|
|
130
|
+
entryTables = allTables.filter((t) => t.includes(q));
|
|
131
|
+
if (entryTables.length === 0) {
|
|
132
|
+
for (const table of allTables) {
|
|
133
|
+
const { columns } = parseTableFile(join(tablesDir, `${table}.md`));
|
|
134
|
+
if (columns.some((c) => c.name.toLowerCase().includes(q)))
|
|
135
|
+
entryTables.push(table);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Load relationships
|
|
139
|
+
const relsFile = join(schemaDir, "relationships.json");
|
|
140
|
+
const rels = existsSync(relsFile) ? JSON.parse(readFileSync(relsFile, "utf-8")) : {};
|
|
141
|
+
// Load functions
|
|
142
|
+
const funcsFile = join(schemaDir, "functions.md");
|
|
143
|
+
const matchingFuncs = [];
|
|
144
|
+
if (existsSync(funcsFile)) {
|
|
145
|
+
for (const line of readFileSync(funcsFile, "utf-8").split("\n")) {
|
|
146
|
+
if (line.startsWith("## ") && line.toLowerCase().includes(q)) {
|
|
147
|
+
matchingFuncs.push(line.replace("## ", ""));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (jsonMode) {
|
|
152
|
+
const result = entryTables.slice(0, 5).map((table) => {
|
|
153
|
+
const { columns, notes } = parseTableFile(join(tablesDir, `${table}.md`));
|
|
154
|
+
return { name: table, columns, notes };
|
|
155
|
+
});
|
|
156
|
+
write(JSON.stringify({ entryTables: result, functions: matchingFuncs }, null, 2) + "\n");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (entryTables.length === 0 && matchingFuncs.length === 0) {
|
|
160
|
+
write(`No tables or columns match "${query}"\n`);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
write(`\n# Context for "${query}"\n\n`);
|
|
164
|
+
for (const table of entryTables.slice(0, 5)) {
|
|
165
|
+
const { columns, notes } = parseTableFile(join(tablesDir, `${table}.md`));
|
|
166
|
+
write(`## ${table}\n`);
|
|
167
|
+
write(`${columns.length} columns | ${columns.filter((c) => c.isPk).length} PK | ${columns.filter((c) => c.fk).length} FK\n\n`);
|
|
168
|
+
write("| Column | Type | Nullable | Default | FK |\n");
|
|
169
|
+
write("|--------|------|----------|---------|----|");
|
|
170
|
+
for (const col of columns) {
|
|
171
|
+
const pk = col.isPk ? " **PK**" : "";
|
|
172
|
+
write(`\n| ${col.name}${pk} | ${col.type} | ${col.nullable} | ${col.defaultVal} | ${col.fk} |`);
|
|
173
|
+
}
|
|
174
|
+
write("\n\n");
|
|
175
|
+
if (notes.length > 0) {
|
|
176
|
+
for (const note of notes)
|
|
177
|
+
write(`${note}\n`);
|
|
178
|
+
write("\n");
|
|
179
|
+
}
|
|
180
|
+
// Find related tables via relationships
|
|
181
|
+
const outgoing = [];
|
|
182
|
+
const incoming = [];
|
|
183
|
+
for (const [from, to] of Object.entries(rels)) {
|
|
184
|
+
const [fromTable] = from.split(".");
|
|
185
|
+
const [toTable] = to.split(".");
|
|
186
|
+
if (fromTable === table)
|
|
187
|
+
outgoing.push(` → ${toTable} via ${from.split(".")[1]} → ${to}`);
|
|
188
|
+
if (toTable === table)
|
|
189
|
+
incoming.push(` ← ${fromTable} via ${from}`);
|
|
190
|
+
}
|
|
191
|
+
if (outgoing.length > 0 || incoming.length > 0) {
|
|
192
|
+
write("### Related Tables\n\n");
|
|
193
|
+
if (outgoing.length > 0) {
|
|
194
|
+
write("**References (this table points to):**\n");
|
|
195
|
+
outgoing.forEach((r) => write(r + "\n"));
|
|
196
|
+
write("\n");
|
|
197
|
+
}
|
|
198
|
+
if (incoming.length > 0) {
|
|
199
|
+
write("**Referenced by (points to this table):**\n");
|
|
200
|
+
incoming.forEach((r) => write(r + "\n"));
|
|
201
|
+
write("\n");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
write("---\n\n");
|
|
205
|
+
}
|
|
206
|
+
if (matchingFuncs.length > 0) {
|
|
207
|
+
write("## Related Functions\n\n");
|
|
208
|
+
for (const func of matchingFuncs)
|
|
209
|
+
write(`- \`${func}\`\n`);
|
|
210
|
+
write("\n");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export function contextCommand() {
|
|
214
|
+
return new Command("context")
|
|
215
|
+
.description("Get comprehensive context for a table or topic — related tables, FKs, functions, column details")
|
|
216
|
+
.argument("<query>", "Table name or topic (e.g., 'episodes', 'user subscriptions', 'chat')")
|
|
217
|
+
.option("--dir <dir>", "Schema directory", ".supabase-schema")
|
|
218
|
+
.option("--depth <n>", "FK traversal depth", "2")
|
|
219
|
+
.option("--json", "Output as JSON")
|
|
220
|
+
.action((query, opts) => {
|
|
221
|
+
const schemaDir = join(process.cwd(), opts.dir);
|
|
222
|
+
const depth = parseInt(opts.depth, 10);
|
|
223
|
+
if (!existsSync(schemaDir)) {
|
|
224
|
+
write(`No schema snapshot found at ${opts.dir}/\n`);
|
|
225
|
+
write("Run `supabase-skill snapshot` first.\n");
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
if (hasDb(schemaDir)) {
|
|
229
|
+
runSqlite(schemaDir, query, depth, !!opts.json);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
runMarkdown(schemaDir, query, depth, !!opts.json);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { readConfig } from "../util/config.js";
|
|
5
|
+
function write(msg) {
|
|
6
|
+
process.stdout.write(msg);
|
|
7
|
+
}
|
|
8
|
+
function getSnapshotCommand(projectDir, ref) {
|
|
9
|
+
const binPath = resolve(process.argv[1]);
|
|
10
|
+
return `cd "${projectDir}" && "${binPath}" snapshot --project-ref ${ref} --output .supabase-schema 2>&1 >> /tmp/supabase-skill-cron.log`;
|
|
11
|
+
}
|
|
12
|
+
function getCrontab() {
|
|
13
|
+
try {
|
|
14
|
+
return execSync("crontab -l 2>/dev/null", { encoding: "utf-8" });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function setCrontab(content) {
|
|
21
|
+
execSync(`echo '${content.replace(/'/g, "'\\''")}' | crontab -`, { encoding: "utf-8" });
|
|
22
|
+
}
|
|
23
|
+
const MARKER = "# supabase-skill snapshot";
|
|
24
|
+
export function cronCommand() {
|
|
25
|
+
return new Command("cron")
|
|
26
|
+
.description("Set up nightly cron job to auto-refresh schema snapshot")
|
|
27
|
+
.option("--time <HH:MM>", "Time to run (24h format)", "03:00")
|
|
28
|
+
.option("--remove", "Remove the cron job")
|
|
29
|
+
.option("--status", "Show current cron status")
|
|
30
|
+
.action((opts) => {
|
|
31
|
+
const config = readConfig();
|
|
32
|
+
const cwd = process.cwd();
|
|
33
|
+
if (opts.status) {
|
|
34
|
+
const crontab = getCrontab();
|
|
35
|
+
const existing = crontab.split("\n").filter((l) => l.includes(MARKER) || (l.trim() && !l.startsWith("#") && l.includes("supabase-skill")));
|
|
36
|
+
if (existing.length > 0) {
|
|
37
|
+
write("Active supabase-skill cron jobs:\n");
|
|
38
|
+
for (const line of existing) {
|
|
39
|
+
if (!line.startsWith("#"))
|
|
40
|
+
write(` ${line}\n`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
write("No supabase-skill cron jobs configured.\n");
|
|
45
|
+
write("Run `supabase-skill cron` to set up nightly snapshot refresh.\n");
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (opts.remove) {
|
|
50
|
+
const crontab = getCrontab();
|
|
51
|
+
const lines = crontab.split("\n");
|
|
52
|
+
const filtered = [];
|
|
53
|
+
let skipNext = false;
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
if (line.includes(MARKER)) {
|
|
56
|
+
skipNext = true;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (skipNext && line.includes("supabase-skill")) {
|
|
60
|
+
skipNext = false;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
skipNext = false;
|
|
64
|
+
filtered.push(line);
|
|
65
|
+
}
|
|
66
|
+
const newCrontab = filtered.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
67
|
+
setCrontab(newCrontab);
|
|
68
|
+
write("Removed supabase-skill cron job.\n");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Set up cron
|
|
72
|
+
let ref;
|
|
73
|
+
if (config) {
|
|
74
|
+
const stageEnv = config.environments["stage"] || config.environments[config.defaultEnv];
|
|
75
|
+
if (stageEnv)
|
|
76
|
+
ref = stageEnv.ref;
|
|
77
|
+
}
|
|
78
|
+
if (!ref) {
|
|
79
|
+
write("No environment configured. Run `supabase-skill install` first.\n");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const [hour, minute] = opts.time.split(":");
|
|
83
|
+
const cronExpr = `${minute || "0"} ${hour || "3"} * * *`;
|
|
84
|
+
const cmd = getSnapshotCommand(cwd, ref);
|
|
85
|
+
// Remove existing entry if present
|
|
86
|
+
let crontab = getCrontab();
|
|
87
|
+
const lines = crontab.split("\n");
|
|
88
|
+
const filtered = [];
|
|
89
|
+
let skipNext = false;
|
|
90
|
+
for (const line of lines) {
|
|
91
|
+
if (line.includes(MARKER)) {
|
|
92
|
+
skipNext = true;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (skipNext && line.includes("supabase-skill")) {
|
|
96
|
+
skipNext = false;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
skipNext = false;
|
|
100
|
+
filtered.push(line);
|
|
101
|
+
}
|
|
102
|
+
crontab = filtered.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
103
|
+
// Add new entry
|
|
104
|
+
const newEntry = `${MARKER} (${cwd})\n${cronExpr} ${cmd}`;
|
|
105
|
+
const newCrontab = crontab ? `${crontab}\n\n${newEntry}` : newEntry;
|
|
106
|
+
setCrontab(newCrontab);
|
|
107
|
+
write(`\n Cron job configured:\n`);
|
|
108
|
+
write(` Schedule: ${cronExpr} (${opts.time} daily)\n`);
|
|
109
|
+
write(` Project: ${cwd}\n`);
|
|
110
|
+
write(` Ref: ${ref}\n`);
|
|
111
|
+
write(` Log: /tmp/supabase-skill-cron.log\n\n`);
|
|
112
|
+
write(` To check status: supabase-skill cron --status\n`);
|
|
113
|
+
write(` To remove: supabase-skill cron --remove\n\n`);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=cron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/commands/cron.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readConfig } from "../util/config.js";
|
|
3
|
+
function buildEnvSection(config) {
|
|
4
|
+
if (!config || Object.keys(config.environments).length === 0) {
|
|
5
|
+
return `### Environments
|
|
6
|
+
- Configure with \`supabase-skill install\` to set project refs
|
|
7
|
+
- Use \`--project-ref <ref>\` with every remote command`;
|
|
8
|
+
}
|
|
9
|
+
const lines = ["### Environments"];
|
|
10
|
+
for (const [env, { ref, name }] of Object.entries(config.environments)) {
|
|
11
|
+
const warning = env === "prod" ? " — \u26a0\ufe0f NEVER modify without explicit approval" : "";
|
|
12
|
+
const label = env.toUpperCase();
|
|
13
|
+
lines.push(`- **${label}**: \`${ref}\` (${name})${warning}`);
|
|
14
|
+
}
|
|
15
|
+
// Add safety reminder
|
|
16
|
+
if (config.environments["prod"]) {
|
|
17
|
+
lines.push(`- **Default**: Use STAGE for testing. PROD requires explicit approval.`);
|
|
18
|
+
}
|
|
19
|
+
return lines.join("\n");
|
|
20
|
+
}
|
|
21
|
+
export function getSkillDoc(config = null) {
|
|
22
|
+
const envSection = buildEnvSection(config);
|
|
23
|
+
return `## supabase-cli (Supabase Database & Infrastructure)
|
|
24
|
+
|
|
25
|
+
Requires: \`supabase\` CLI installed, logged in via \`supabase login\`.
|
|
26
|
+
All commands support \`-o json\` for structured output.
|
|
27
|
+
|
|
28
|
+
${envSection}
|
|
29
|
+
|
|
30
|
+
### SQL Execution (daily use)
|
|
31
|
+
- \`supabase db execute --project-ref <ref> --stdin <<< "SELECT 1"\` — run inline SQL
|
|
32
|
+
- \`supabase db execute --project-ref <ref> -f path/to/file.sql\` — run SQL file
|
|
33
|
+
|
|
34
|
+
### Migrations
|
|
35
|
+
- \`supabase migration new <name>\` — create empty migration file
|
|
36
|
+
- \`supabase migration list --project-ref <ref>\` — compare local vs remote
|
|
37
|
+
- \`supabase migration up --project-ref <ref>\` — apply pending to remote
|
|
38
|
+
- \`supabase migration down --project-ref <ref> -n 1\` — rollback last N migrations
|
|
39
|
+
- \`supabase migration repair --status applied <version> --project-ref <ref>\` — mark version as applied
|
|
40
|
+
- \`supabase migration repair --status reverted <version> --project-ref <ref>\` — mark version as reverted
|
|
41
|
+
- \`supabase migration squash --project-ref <ref>\` — combine into single file
|
|
42
|
+
- \`supabase migration fetch --project-ref <ref>\` — pull history from remote
|
|
43
|
+
|
|
44
|
+
### Schema Management
|
|
45
|
+
- \`supabase db diff --project-ref <ref>\` — diff local vs remote schema
|
|
46
|
+
- \`supabase db dump --project-ref <ref>\` — dump full schema
|
|
47
|
+
- \`supabase db dump --project-ref <ref> --data-only\` — dump data only
|
|
48
|
+
- \`supabase db dump --project-ref <ref> --schema <name>\` — dump specific schema
|
|
49
|
+
- \`supabase db pull --project-ref <ref>\` — pull remote schema to local migrations
|
|
50
|
+
- \`supabase db push --project-ref <ref>\` — push migrations to remote
|
|
51
|
+
- \`supabase db lint\` — check for typing errors
|
|
52
|
+
|
|
53
|
+
### Database Inspection (debugging/support)
|
|
54
|
+
- \`supabase inspect db table-stats --project-ref <ref>\` — table sizes + row counts
|
|
55
|
+
- \`supabase inspect db index-stats --project-ref <ref>\` — index usage + scan counts
|
|
56
|
+
- \`supabase inspect db long-running-queries --project-ref <ref>\` — queries > 5min
|
|
57
|
+
- \`supabase inspect db outliers --project-ref <ref>\` — slowest queries by total time
|
|
58
|
+
- \`supabase inspect db bloat --project-ref <ref>\` — dead tuple estimation
|
|
59
|
+
- \`supabase inspect db locks --project-ref <ref>\` — active locks
|
|
60
|
+
- \`supabase inspect db blocking --project-ref <ref>\` — blocking lock chains
|
|
61
|
+
- \`supabase inspect db db-stats --project-ref <ref>\` — cache hit rates, WAL, sizes
|
|
62
|
+
- \`supabase inspect db vacuum-stats --project-ref <ref>\` — vacuum status per table
|
|
63
|
+
- \`supabase inspect db role-stats --project-ref <ref>\` — role information
|
|
64
|
+
- \`supabase inspect db replication-slots --project-ref <ref>\` — replication status
|
|
65
|
+
- \`supabase inspect report --project-ref <ref>\` — CSV of ALL inspect commands
|
|
66
|
+
|
|
67
|
+
### Storage
|
|
68
|
+
- \`supabase storage ls ss://bucket/path --project-ref <ref>\` — list objects
|
|
69
|
+
- \`supabase storage cp local.file ss://bucket/path --project-ref <ref>\` — upload
|
|
70
|
+
- \`supabase storage cp ss://bucket/path local.file --project-ref <ref>\` — download
|
|
71
|
+
- \`supabase storage rm ss://bucket/path --project-ref <ref>\` — delete
|
|
72
|
+
- \`supabase storage mv ss://old ss://new --project-ref <ref>\` — move/rename
|
|
73
|
+
|
|
74
|
+
### Edge Functions
|
|
75
|
+
- \`supabase functions list --project-ref <ref>\` — list deployed functions
|
|
76
|
+
- \`supabase functions deploy <name> --project-ref <ref>\` — deploy function
|
|
77
|
+
- \`supabase functions delete <name> --project-ref <ref>\` — delete function
|
|
78
|
+
- \`supabase functions serve\` — serve locally for testing
|
|
79
|
+
|
|
80
|
+
### Project Management
|
|
81
|
+
- \`supabase projects list -o json\` — list all projects
|
|
82
|
+
- \`supabase projects api-keys --project-ref <ref> -o json\` — get API keys
|
|
83
|
+
- \`supabase secrets list --project-ref <ref>\` — list env secrets
|
|
84
|
+
- \`supabase secrets set KEY=VALUE --project-ref <ref>\` — set secret
|
|
85
|
+
|
|
86
|
+
### SQL Snippets (from dashboard)
|
|
87
|
+
- \`supabase snippets list --project-ref <ref> -o json\` — list saved snippets
|
|
88
|
+
- \`supabase snippets download <id> --project-ref <ref>\` — download snippet SQL
|
|
89
|
+
|
|
90
|
+
### Setup
|
|
91
|
+
- \`supabase-skill install\` — global setup (interactive wizard, adds to ~/.claude/CLAUDE.md)
|
|
92
|
+
- \`supabase-skill init\` — per-project setup (CLAUDE.md + .env + .gitignore)
|
|
93
|
+
- \`supabase-skill docs\` — output LLM instruction snippet
|
|
94
|
+
- \`supabase-skill docs --format claude\` — CLAUDE.md format
|
|
95
|
+
- \`supabase-skill envs\` — list configured environments
|
|
96
|
+
|
|
97
|
+
### Schema Snapshot (local DB map — use INSTEAD of querying information_schema)
|
|
98
|
+
If \`.supabase-schema/\` exists, ALWAYS use these commands instead of running SQL to explore the schema:
|
|
99
|
+
- \`supabase-skill snapshot\` — snapshot schema to .supabase-schema/ (tables, columns, FKs, functions)
|
|
100
|
+
- \`supabase-skill snapshot --project-ref <ref>\` — snapshot a specific environment
|
|
101
|
+
- \`supabase-skill context <table-or-topic>\` — get full context: columns, FKs, related tables (2 levels deep), related functions
|
|
102
|
+
- \`supabase-skill context <topic> --depth 3\` — deeper FK traversal
|
|
103
|
+
- \`supabase-skill table <name>\` — full single-table detail with relationships, functions, related table summaries
|
|
104
|
+
- \`supabase-skill columns --type <type>\` — find all columns of a type (uuid, jsonb, text, timestamp, etc.)
|
|
105
|
+
- \`supabase-skill columns --fk\` — find all foreign key columns
|
|
106
|
+
- \`supabase-skill columns --table <name>\` — filter columns to specific table
|
|
107
|
+
- \`supabase-skill columns <name> --type jsonb\` — combine name + type filters
|
|
108
|
+
- \`supabase-skill search <query>\` — search tables, columns, functions, and relationships
|
|
109
|
+
- \`supabase-skill search <query> --json\` — structured JSON output
|
|
110
|
+
- Read \`.supabase-schema/tables/<name>.md\` — full table schema (columns, types, PKs, FKs, defaults)
|
|
111
|
+
- Read \`.supabase-schema/index.md\` — overview of all tables, views, functions
|
|
112
|
+
- Read \`.supabase-schema/relationships.json\` — all foreign key mappings
|
|
113
|
+
- Read \`.supabase-schema/functions.md\` — all RPC functions with parameters
|
|
114
|
+
|
|
115
|
+
### Schema Snapshot Auto-Refresh
|
|
116
|
+
- Snapshot refreshes nightly via cron (if configured with \`supabase-skill cron\`)
|
|
117
|
+
- **After applying migrations**: Run \`supabase-skill snapshot\` to update the local schema cache
|
|
118
|
+
- **After creating/altering tables**: Run \`supabase-skill snapshot\` before continuing work
|
|
119
|
+
- **Rule of thumb**: If you ran any DDL (CREATE, ALTER, DROP) or migration commands, refresh the snapshot immediately
|
|
120
|
+
|
|
121
|
+
### Safety Rules
|
|
122
|
+
- NEVER run mutations on PROD without explicit user approval
|
|
123
|
+
- ALWAYS specify \`--project-ref\` — never rely on linked project for remote ops
|
|
124
|
+
- Use \`-o json\` for structured output the agent can parse
|
|
125
|
+
- Run \`supabase migration list\` BEFORE and AFTER migration operations
|
|
126
|
+
- Test migrations on STAGE before applying to PROD
|
|
127
|
+
|
|
128
|
+
### Exit codes
|
|
129
|
+
- 0 = success, 1 = error`;
|
|
130
|
+
}
|
|
131
|
+
const FORMATS = {
|
|
132
|
+
claude: {
|
|
133
|
+
filename: "CLAUDE.md",
|
|
134
|
+
wrap: (c) => c,
|
|
135
|
+
},
|
|
136
|
+
agents: {
|
|
137
|
+
filename: "AGENTS.md",
|
|
138
|
+
wrap: (c) => c,
|
|
139
|
+
},
|
|
140
|
+
cursor: {
|
|
141
|
+
filename: ".cursorrules",
|
|
142
|
+
wrap: (c) => c,
|
|
143
|
+
},
|
|
144
|
+
skill: {
|
|
145
|
+
filename: "SKILL.md",
|
|
146
|
+
wrap: (c) => `---
|
|
147
|
+
name: supabase-skill
|
|
148
|
+
description: Manage Supabase databases, migrations, storage, and edge functions via CLI. Multi-environment support (dev/stage/prod).
|
|
149
|
+
metadata:
|
|
150
|
+
requires:
|
|
151
|
+
env:
|
|
152
|
+
- SUPABASE_ACCESS_TOKEN
|
|
153
|
+
bins:
|
|
154
|
+
- supabase
|
|
155
|
+
primaryEnv: SUPABASE_ACCESS_TOKEN
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
# supabase-skill
|
|
159
|
+
|
|
160
|
+
${c}`,
|
|
161
|
+
},
|
|
162
|
+
raw: {
|
|
163
|
+
filename: "",
|
|
164
|
+
wrap: (c) => c,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
export function docsCommand() {
|
|
168
|
+
return new Command("docs")
|
|
169
|
+
.description("Generate LLM instruction snippet for supabase-skill. Outputs to stdout.")
|
|
170
|
+
.option("--format <type>", "Output format: claude, agents, cursor, skill, raw (default: raw)", "raw")
|
|
171
|
+
.action((opts) => {
|
|
172
|
+
const fmt = FORMATS[opts.format];
|
|
173
|
+
if (!fmt) {
|
|
174
|
+
process.stderr.write(`Unknown format: ${opts.format}. Use: ${Object.keys(FORMATS).join(", ")}\n`);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
const config = readConfig();
|
|
178
|
+
const doc = getSkillDoc(config);
|
|
179
|
+
process.stdout.write(fmt.wrap(doc) + "\n");
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readConfig } from "../util/config.js";
|
|
3
|
+
export function envsCommand() {
|
|
4
|
+
return new Command("envs")
|
|
5
|
+
.description("List configured Supabase environments")
|
|
6
|
+
.action(() => {
|
|
7
|
+
const config = readConfig();
|
|
8
|
+
if (!config || Object.keys(config.environments).length === 0) {
|
|
9
|
+
process.stdout.write("No environments configured.\n");
|
|
10
|
+
process.stdout.write("Run `supabase-skill install` to set up environments.\n");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
process.stdout.write("\nConfigured environments:\n");
|
|
14
|
+
for (const [env, { ref, name }] of Object.entries(config.environments)) {
|
|
15
|
+
const isDefault = env === config.defaultEnv ? " (default)" : "";
|
|
16
|
+
const isProd = env === "prod" ? " \u26a0\ufe0f" : "";
|
|
17
|
+
process.stdout.write(` ${env.toUpperCase()}: ${ref} — ${name}${isDefault}${isProd}\n`);
|
|
18
|
+
}
|
|
19
|
+
process.stdout.write("\n");
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=envs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envs.js","sourceRoot":"","sources":["../../src/commands/envs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACrD,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACvE,MAAM,SAAS,GAAG,GAAG,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG,MAAM,IAAI,GAAG,SAAS,GAAG,MAAM,IAAI,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACP,CAAC"}
|