axgram 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 +126 -0
- package/dist/bin/axgram-hook.js +77 -0
- package/dist/bin/axgram-hook.js.map +1 -0
- package/dist/bin/axgram.js +386 -0
- package/dist/bin/axgram.js.map +1 -0
- package/dist/commands/hook-session-start.js +85 -0
- package/dist/commands/hook-session-start.js.map +1 -0
- package/dist/commands/hook-stop.js +73 -0
- package/dist/commands/hook-stop.js.map +1 -0
- package/dist/commands/import.js +56 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/invitations.js +153 -0
- package/dist/commands/invitations.js.map +1 -0
- package/dist/commands/login.js +125 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +11 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/members.js +231 -0
- package/dist/commands/members.js.map +1 -0
- package/dist/commands/mine.js +78 -0
- package/dist/commands/mine.js.map +1 -0
- package/dist/commands/orgs.js +153 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/projects.js +285 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/teams.js +153 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/auth.js +128 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/chunkers/exchange-pair.js +51 -0
- package/dist/lib/chunkers/exchange-pair.js.map +1 -0
- package/dist/lib/chunkers/index.js +74 -0
- package/dist/lib/chunkers/index.js.map +1 -0
- package/dist/lib/chunkers/line-group.js +20 -0
- package/dist/lib/chunkers/line-group.js.map +1 -0
- package/dist/lib/chunkers/paragraph.js +29 -0
- package/dist/lib/chunkers/paragraph.js.map +1 -0
- package/dist/lib/chunkers/types.js +3 -0
- package/dist/lib/chunkers/types.js.map +1 -0
- package/dist/lib/config-dir.js +30 -0
- package/dist/lib/config-dir.js.map +1 -0
- package/dist/lib/destructive-confirm.js +71 -0
- package/dist/lib/destructive-confirm.js.map +1 -0
- package/dist/lib/entity-extractor.js +182 -0
- package/dist/lib/entity-extractor.js.map +1 -0
- package/dist/lib/global-config.js +42 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/hook-settings.js +87 -0
- package/dist/lib/hook-settings.js.map +1 -0
- package/dist/lib/hook-state.js +38 -0
- package/dist/lib/hook-state.js.map +1 -0
- package/dist/lib/importers/chatgpt.js +89 -0
- package/dist/lib/importers/chatgpt.js.map +1 -0
- package/dist/lib/importers/claude.js +47 -0
- package/dist/lib/importers/claude.js.map +1 -0
- package/dist/lib/importers/gemini.js +38 -0
- package/dist/lib/importers/gemini.js.map +1 -0
- package/dist/lib/importers/markdown.js +47 -0
- package/dist/lib/importers/markdown.js.map +1 -0
- package/dist/lib/importers/obsidian.js +62 -0
- package/dist/lib/importers/obsidian.js.map +1 -0
- package/dist/lib/importers/run.js +51 -0
- package/dist/lib/importers/run.js.map +1 -0
- package/dist/lib/ingest.js +101 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/mcp-client.js +56 -0
- package/dist/lib/mcp-client.js.map +1 -0
- package/dist/lib/project-resolver.js +42 -0
- package/dist/lib/project-resolver.js.map +1 -0
- package/dist/lib/remote-url.js +23 -0
- package/dist/lib/remote-url.js.map +1 -0
- package/dist/lib/repo-bindings.js +52 -0
- package/dist/lib/repo-bindings.js.map +1 -0
- package/dist/lib/repo.js +72 -0
- package/dist/lib/repo.js.map +1 -0
- package/dist/lib/room-detector.js +99 -0
- package/dist/lib/room-detector.js.map +1 -0
- package/dist/lib/slugify.js +17 -0
- package/dist/lib/slugify.js.map +1 -0
- package/dist/lib/supabase-client.js +35 -0
- package/dist/lib/supabase-client.js.map +1 -0
- package/dist/lib/tool-vocab.js +114 -0
- package/dist/lib/tool-vocab.js.map +1 -0
- package/dist/lib/transcript.js +68 -0
- package/dist/lib/transcript.js.map +1 -0
- package/dist/lib/walker.js +81 -0
- package/dist/lib/walker.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.projectsLs = projectsLs;
|
|
7
|
+
exports.projectsUse = projectsUse;
|
|
8
|
+
exports.projectsCreate = projectsCreate;
|
|
9
|
+
exports.projectsLink = projectsLink;
|
|
10
|
+
exports.projectsUnlink = projectsUnlink;
|
|
11
|
+
exports.projectsCurrent = projectsCurrent;
|
|
12
|
+
exports.projectsClearDefault = projectsClearDefault;
|
|
13
|
+
exports.projectsDelete = projectsDelete;
|
|
14
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
15
|
+
const supabase_client_1 = require("../lib/supabase-client");
|
|
16
|
+
const global_config_1 = require("../lib/global-config");
|
|
17
|
+
const project_resolver_1 = require("../lib/project-resolver");
|
|
18
|
+
const repo_1 = require("../lib/repo");
|
|
19
|
+
const repo_bindings_1 = require("../lib/repo-bindings");
|
|
20
|
+
const destructive_confirm_1 = require("../lib/destructive-confirm");
|
|
21
|
+
const defaultLog = (m) => process.stdout.write(`${m}\n`);
|
|
22
|
+
const defaultErr = (m) => process.stderr.write(`${m}\n`);
|
|
23
|
+
async function buildSupabase(deps) {
|
|
24
|
+
return deps.supabaseFactory
|
|
25
|
+
? deps.supabaseFactory()
|
|
26
|
+
: (0, supabase_client_1.authenticatedSupabase)();
|
|
27
|
+
}
|
|
28
|
+
async function fetchProjects(supabase) {
|
|
29
|
+
const { data, error } = await supabase
|
|
30
|
+
.from("projects")
|
|
31
|
+
.select("id,name,description,teams!inner(id,name,orgs!inner(id,name))")
|
|
32
|
+
.order("name");
|
|
33
|
+
if (error)
|
|
34
|
+
throw new Error(`Failed to list projects: ${error.message}`);
|
|
35
|
+
// PostgREST returns related rows as arrays in supabase-js's default typing;
|
|
36
|
+
// for these many-to-one joins the array always has exactly one element.
|
|
37
|
+
// Coerce shape rather than fighting the inferred Database<unknown> types.
|
|
38
|
+
const rows = (data ?? []);
|
|
39
|
+
return rows.map((row) => ({
|
|
40
|
+
id: row.id,
|
|
41
|
+
name: row.name,
|
|
42
|
+
description: row.description,
|
|
43
|
+
team: {
|
|
44
|
+
id: row.teams.id,
|
|
45
|
+
name: row.teams.name,
|
|
46
|
+
org: { id: row.teams.orgs.id, name: row.teams.orgs.name },
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
async function projectsLs(deps = {}) {
|
|
51
|
+
const log = deps.log ?? defaultLog;
|
|
52
|
+
const supabase = await buildSupabase(deps);
|
|
53
|
+
const projects = await fetchProjects(supabase);
|
|
54
|
+
if (projects.length === 0) {
|
|
55
|
+
log("No projects accessible. Create one with `axgram projects create <name>`.");
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
for (const p of projects) {
|
|
59
|
+
log(`${p.id} ${p.team.org.name}/${p.team.name}/${p.name}` +
|
|
60
|
+
(p.description ? ` — ${p.description}` : ""));
|
|
61
|
+
}
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
async function projectsUse(projectId, deps = {}) {
|
|
65
|
+
const log = deps.log ?? defaultLog;
|
|
66
|
+
const supabase = await buildSupabase(deps);
|
|
67
|
+
const projects = await fetchProjects(supabase);
|
|
68
|
+
const target = projects.find((p) => p.id === projectId || p.name.toLowerCase() === projectId.toLowerCase());
|
|
69
|
+
if (!target) {
|
|
70
|
+
(deps.err ?? defaultErr)(`No accessible project matches '${projectId}'. Run \`axgram projects ls\` to see options.`);
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
await (0, global_config_1.setDefaultProject)(target.id);
|
|
74
|
+
log(`Default project set to ${target.name} (${target.id}).`);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
async function projectsCreate(name, options = {}, deps = {}) {
|
|
78
|
+
const log = deps.log ?? defaultLog;
|
|
79
|
+
const errOut = deps.err ?? defaultErr;
|
|
80
|
+
const supabase = await buildSupabase(deps);
|
|
81
|
+
let teamId = options.teamId;
|
|
82
|
+
if (!teamId) {
|
|
83
|
+
const { data: teams, error } = await supabase
|
|
84
|
+
.from("teams")
|
|
85
|
+
.select("id")
|
|
86
|
+
.order("created_at", { ascending: true })
|
|
87
|
+
.limit(1);
|
|
88
|
+
if (error) {
|
|
89
|
+
errOut(`Could not look up teams: ${error.message}`);
|
|
90
|
+
return 1;
|
|
91
|
+
}
|
|
92
|
+
const first = teams?.[0];
|
|
93
|
+
if (!first) {
|
|
94
|
+
errOut("No accessible teams found. Your account may not be auto-provisioned yet.");
|
|
95
|
+
return 1;
|
|
96
|
+
}
|
|
97
|
+
teamId = first.id;
|
|
98
|
+
}
|
|
99
|
+
// Direct INSERT...RETURNING through RLS fails on the SELECT step
|
|
100
|
+
// because projects_select uses a STABLE-cached `current_user_access().
|
|
101
|
+
// project_ids` that doesn't include the freshly-inserted id. The
|
|
102
|
+
// create_project RPC bypasses that with SECURITY DEFINER + a manual
|
|
103
|
+
// membership check.
|
|
104
|
+
const { data, error } = await supabase.rpc("create_project", {
|
|
105
|
+
p_team_id: teamId,
|
|
106
|
+
p_name: name,
|
|
107
|
+
p_description: options.description ?? null,
|
|
108
|
+
p_identity: options.identity ?? null,
|
|
109
|
+
});
|
|
110
|
+
if (error || !data || !Array.isArray(data) || data.length === 0) {
|
|
111
|
+
errOut(`Failed to create project: ${error?.message ?? "unknown error"}`);
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
const created = data[0];
|
|
115
|
+
log(`Created project ${created.name} (${created.id}).`);
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
async function projectsLink(projectId, deps = {}) {
|
|
119
|
+
const log = deps.log ?? defaultLog;
|
|
120
|
+
const errOut = deps.err ?? defaultErr;
|
|
121
|
+
const repoUrl = await (0, repo_1.getCurrentRepoUrl)(deps.cwd);
|
|
122
|
+
if (!repoUrl) {
|
|
123
|
+
errOut("Not a git repository (or no `origin` remote). Run `git remote add origin <url>` or use `--project` on individual commands.");
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
const repoKey = (0, repo_1.normalizeRepoUrl)(repoUrl);
|
|
127
|
+
if (!repoKey) {
|
|
128
|
+
errOut(`Could not parse origin URL: ${repoUrl}`);
|
|
129
|
+
return 1;
|
|
130
|
+
}
|
|
131
|
+
let chosenId = projectId;
|
|
132
|
+
if (!chosenId) {
|
|
133
|
+
const supabase = await buildSupabase(deps);
|
|
134
|
+
const projects = await fetchProjects(supabase);
|
|
135
|
+
if (projects.length === 0) {
|
|
136
|
+
errOut("No projects accessible. Create one first with `axgram projects create <name>`.");
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
const picker = deps.pickProject ?? defaultPicker(deps.log ?? defaultLog);
|
|
140
|
+
const picked = await picker(projects);
|
|
141
|
+
if (!picked) {
|
|
142
|
+
log("Cancelled.");
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
chosenId = picked;
|
|
146
|
+
}
|
|
147
|
+
await (0, repo_bindings_1.setBinding)(repoKey, chosenId);
|
|
148
|
+
log(`Linked ${repoKey} → ${chosenId}.`);
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
async function projectsUnlink(deps = {}) {
|
|
152
|
+
const log = deps.log ?? defaultLog;
|
|
153
|
+
const errOut = deps.err ?? defaultErr;
|
|
154
|
+
const repoUrl = await (0, repo_1.getCurrentRepoUrl)(deps.cwd);
|
|
155
|
+
if (!repoUrl) {
|
|
156
|
+
errOut("Not a git repository.");
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
const repoKey = (0, repo_1.normalizeRepoUrl)(repoUrl);
|
|
160
|
+
if (!repoKey) {
|
|
161
|
+
errOut(`Could not parse origin URL: ${repoUrl}`);
|
|
162
|
+
return 1;
|
|
163
|
+
}
|
|
164
|
+
const removed = await (0, repo_bindings_1.removeBinding)(repoKey);
|
|
165
|
+
log(removed ? `Unlinked ${repoKey}.` : `No binding for ${repoKey}.`);
|
|
166
|
+
return removed ? 0 : 1;
|
|
167
|
+
}
|
|
168
|
+
async function projectsCurrent(flag, deps = {}) {
|
|
169
|
+
const log = deps.log ?? defaultLog;
|
|
170
|
+
const errOut = deps.err ?? defaultErr;
|
|
171
|
+
const resolved = await (0, project_resolver_1.resolveActiveProject)({
|
|
172
|
+
flag,
|
|
173
|
+
...(deps.cwd ? { cwd: deps.cwd } : {}),
|
|
174
|
+
});
|
|
175
|
+
if (resolved.projectId) {
|
|
176
|
+
log(`${resolved.projectId} (source: ${resolved.source})`);
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
errOut(resolved.repoKey
|
|
180
|
+
? `No project bound to ${resolved.repoKey}. Run \`axgram projects link\` to bind one.`
|
|
181
|
+
: "No active project. Set AXGRAM_PROJECT_ID, run `axgram projects use <id>`, or `axgram projects link` from inside a git repo.");
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
async function projectsClearDefault(deps = {}) {
|
|
185
|
+
const log = deps.log ?? defaultLog;
|
|
186
|
+
await (0, global_config_1.clearDefaultProject)();
|
|
187
|
+
log("Global default project cleared.");
|
|
188
|
+
return 0;
|
|
189
|
+
}
|
|
190
|
+
function defaultPicker(log) {
|
|
191
|
+
return async (projects) => {
|
|
192
|
+
log("Available projects:");
|
|
193
|
+
projects.forEach((p, i) => {
|
|
194
|
+
log(` ${i + 1}. ${p.team.org.name}/${p.team.name}/${p.name} (${p.id})`);
|
|
195
|
+
});
|
|
196
|
+
if (!process.stdin.isTTY) {
|
|
197
|
+
// Refuse to silently default in a non-interactive context — the
|
|
198
|
+
// caller almost certainly meant to pass a project_id explicitly.
|
|
199
|
+
log("stdin is not a TTY; pass the project_id directly: `axgram projects link <id>`.");
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
const rl = node_readline_1.default.createInterface({
|
|
203
|
+
input: process.stdin,
|
|
204
|
+
output: process.stdout,
|
|
205
|
+
});
|
|
206
|
+
try {
|
|
207
|
+
const answer = await new Promise((res) => {
|
|
208
|
+
rl.question("Pick a project [1-" + projects.length + "]: ", (a) => res(a.trim()));
|
|
209
|
+
});
|
|
210
|
+
const idx = Number.parseInt(answer, 10);
|
|
211
|
+
if (Number.isNaN(idx) || idx < 1 || idx > projects.length) {
|
|
212
|
+
log("Invalid selection.");
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
return projects[idx - 1].id;
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
rl.close();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// Plan 5 Task 9: type-to-confirm project delete via the delete_project RPC.
|
|
223
|
+
// The CLI uses this RPC (not the raw RLS DELETE) so the cascade preview +
|
|
224
|
+
// server-side p_confirm_name validation both fire. Direct DELETE remains
|
|
225
|
+
// available via supabase-js for shipped-behavior compatibility (Plan 3
|
|
226
|
+
// tests rely on it).
|
|
227
|
+
async function projectsDelete(projectIdOrName, options, deps = {}) {
|
|
228
|
+
const log = deps.log ?? defaultLog;
|
|
229
|
+
const errOut = deps.err ?? defaultErr;
|
|
230
|
+
const supabase = await buildSupabase(deps);
|
|
231
|
+
const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(projectIdOrName);
|
|
232
|
+
const q = supabase.from("projects").select("id, name");
|
|
233
|
+
const { data, error } = isUuid
|
|
234
|
+
? await q.eq("id", projectIdOrName).maybeSingle()
|
|
235
|
+
: await q.eq("name", projectIdOrName).maybeSingle();
|
|
236
|
+
if (error) {
|
|
237
|
+
errOut(`Failed to resolve project: ${error.message}`);
|
|
238
|
+
return 1;
|
|
239
|
+
}
|
|
240
|
+
if (!data) {
|
|
241
|
+
errOut(`No project found matching "${projectIdOrName}".`);
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
const target = { id: data.id, name: data.name };
|
|
245
|
+
const { data: counts, error: ce } = await supabase.rpc("count_project_descendants", { p_project_id: target.id });
|
|
246
|
+
if (ce) {
|
|
247
|
+
errOut(`Failed to preview delete: ${ce.message}`);
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
const c = counts[0] ?? {};
|
|
251
|
+
const confirmed = await (0, destructive_confirm_1.confirmDestructive)({
|
|
252
|
+
targetKind: "project",
|
|
253
|
+
targetName: target.name,
|
|
254
|
+
counts: {
|
|
255
|
+
drawers: c.drawers ?? 0,
|
|
256
|
+
closets: c.closets ?? 0,
|
|
257
|
+
tunnels: c.tunnels ?? 0,
|
|
258
|
+
diary_entries: c.diary_entries ?? 0,
|
|
259
|
+
entities: c.entities ?? 0,
|
|
260
|
+
triples: c.triples ?? 0,
|
|
261
|
+
},
|
|
262
|
+
}, options, {
|
|
263
|
+
...(deps.log ? { log: deps.log } : {}),
|
|
264
|
+
...(deps.err ? { err: deps.err } : {}),
|
|
265
|
+
});
|
|
266
|
+
if (!confirmed)
|
|
267
|
+
return 1;
|
|
268
|
+
const res = await supabase.rpc("delete_project", {
|
|
269
|
+
p_project_id: target.id,
|
|
270
|
+
p_confirm_name: confirmed,
|
|
271
|
+
});
|
|
272
|
+
if (res.error) {
|
|
273
|
+
errOut(`Failed to delete project: ${res.error.message}`);
|
|
274
|
+
return 1;
|
|
275
|
+
}
|
|
276
|
+
const result = res.data[0];
|
|
277
|
+
if (!result.ok && result.code === "name_confirmation_mismatch") {
|
|
278
|
+
errOut("Server rejected confirmation (project may have been renamed). Aborted.");
|
|
279
|
+
return 1;
|
|
280
|
+
}
|
|
281
|
+
log(`Deleted project "${target.name}". ` +
|
|
282
|
+
`Removed ${JSON.stringify(result.deleted_counts)}.`);
|
|
283
|
+
return 0;
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Plan 5 Task 9: `axgram teams` subcommands.
|
|
3
|
+
//
|
|
4
|
+
// ls, create (auto-join default; --no-join opt-out), delete (type-to-confirm).
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.teamsLs = teamsLs;
|
|
7
|
+
exports.teamsCreate = teamsCreate;
|
|
8
|
+
exports.teamsDelete = teamsDelete;
|
|
9
|
+
const supabase_client_1 = require("../lib/supabase-client");
|
|
10
|
+
const destructive_confirm_1 = require("../lib/destructive-confirm");
|
|
11
|
+
const defaultLog = (m) => process.stdout.write(`${m}\n`);
|
|
12
|
+
const defaultErr = (m) => process.stderr.write(`${m}\n`);
|
|
13
|
+
const isUuid = (s) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
|
|
14
|
+
async function buildSupabase(deps) {
|
|
15
|
+
return deps.supabaseFactory ? deps.supabaseFactory() : (0, supabase_client_1.authenticatedSupabase)();
|
|
16
|
+
}
|
|
17
|
+
async function resolveOrgId(s, idOrName) {
|
|
18
|
+
const q = s.from("orgs").select("id");
|
|
19
|
+
const { data } = isUuid(idOrName)
|
|
20
|
+
? await q.eq("id", idOrName).maybeSingle()
|
|
21
|
+
: await q.eq("name", idOrName).maybeSingle();
|
|
22
|
+
return data?.id ?? null;
|
|
23
|
+
}
|
|
24
|
+
async function resolveTeam(s, idOrName) {
|
|
25
|
+
const q = s.from("teams").select("id, name");
|
|
26
|
+
const { data } = isUuid(idOrName)
|
|
27
|
+
? await q.eq("id", idOrName).maybeSingle()
|
|
28
|
+
: await q.eq("name", idOrName).maybeSingle();
|
|
29
|
+
if (!data)
|
|
30
|
+
return null;
|
|
31
|
+
return { id: data.id, name: data.name };
|
|
32
|
+
}
|
|
33
|
+
async function teamsLs(orgFlag, deps = {}) {
|
|
34
|
+
const log = deps.log ?? defaultLog;
|
|
35
|
+
const s = await buildSupabase(deps);
|
|
36
|
+
let orgId;
|
|
37
|
+
if (orgFlag) {
|
|
38
|
+
const r = await resolveOrgId(s, orgFlag);
|
|
39
|
+
if (!r) {
|
|
40
|
+
(deps.err ?? defaultErr)(`No org found matching "${orgFlag}".`);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
orgId = r;
|
|
44
|
+
}
|
|
45
|
+
let q = s
|
|
46
|
+
.from("teams")
|
|
47
|
+
.select("id, name, org_id, orgs!inner(id, name), memberships(role)")
|
|
48
|
+
.order("name");
|
|
49
|
+
if (orgId)
|
|
50
|
+
q = q.eq("org_id", orgId);
|
|
51
|
+
const { data, error } = await q;
|
|
52
|
+
if (error) {
|
|
53
|
+
(deps.err ?? defaultErr)(`Failed to list teams: ${error.message}`);
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
if (!data || data.length === 0) {
|
|
57
|
+
log("No teams visible.");
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
for (const t of data) {
|
|
61
|
+
const role = t.memberships?.[0]?.role ?? "—";
|
|
62
|
+
log(`${t.id} [${role}] ${t.orgs.name}/${t.name}`);
|
|
63
|
+
}
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
async function teamsCreate(name, options, deps = {}) {
|
|
67
|
+
const log = deps.log ?? defaultLog;
|
|
68
|
+
const errOut = deps.err ?? defaultErr;
|
|
69
|
+
const s = await buildSupabase(deps);
|
|
70
|
+
let orgId = options.orgId;
|
|
71
|
+
if (!orgId && options.orgName) {
|
|
72
|
+
const r = await resolveOrgId(s, options.orgName);
|
|
73
|
+
if (!r) {
|
|
74
|
+
errOut(`No org found matching "${options.orgName}".`);
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
orgId = r;
|
|
78
|
+
}
|
|
79
|
+
if (!orgId) {
|
|
80
|
+
// Fall back to caller's first org.
|
|
81
|
+
const { data } = await s.from("orgs").select("id").limit(1);
|
|
82
|
+
if (!data || data.length === 0) {
|
|
83
|
+
errOut("No accessible org. Pass --org <id-or-name> or run `axgram orgs create` first.");
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
orgId = data[0].id;
|
|
87
|
+
}
|
|
88
|
+
const { data, error } = await s.rpc("create_team", {
|
|
89
|
+
p_org_id: orgId,
|
|
90
|
+
p_name: name,
|
|
91
|
+
p_join: !options.noJoin,
|
|
92
|
+
});
|
|
93
|
+
if (error) {
|
|
94
|
+
errOut(`Failed to create team: ${error.message}`);
|
|
95
|
+
return 1;
|
|
96
|
+
}
|
|
97
|
+
const row = data[0];
|
|
98
|
+
const joinedNote = options.noJoin ? " (memberless)" : " (you are owner)";
|
|
99
|
+
log(`Created team "${row.name}" (${row.team_id})${joinedNote}.`);
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
async function teamsDelete(teamIdOrName, options, deps = {}) {
|
|
103
|
+
const log = deps.log ?? defaultLog;
|
|
104
|
+
const errOut = deps.err ?? defaultErr;
|
|
105
|
+
const s = await buildSupabase(deps);
|
|
106
|
+
const target = await resolveTeam(s, teamIdOrName);
|
|
107
|
+
if (!target) {
|
|
108
|
+
errOut(`No team found matching "${teamIdOrName}".`);
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
const { data: counts, error: ce } = await s.rpc("count_team_descendants", {
|
|
112
|
+
p_team_id: target.id,
|
|
113
|
+
});
|
|
114
|
+
if (ce) {
|
|
115
|
+
errOut(`Failed to preview delete: ${ce.message}`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
const c = counts[0] ?? {};
|
|
119
|
+
const confirmed = await (0, destructive_confirm_1.confirmDestructive)({
|
|
120
|
+
targetKind: "team",
|
|
121
|
+
targetName: target.name,
|
|
122
|
+
counts: {
|
|
123
|
+
projects: c.projects ?? 0,
|
|
124
|
+
drawers: c.drawers ?? 0,
|
|
125
|
+
memberships: c.memberships ?? 0,
|
|
126
|
+
invitations: c.invitations ?? 0,
|
|
127
|
+
},
|
|
128
|
+
}, options, {
|
|
129
|
+
...(deps.log ? { log: deps.log } : {}),
|
|
130
|
+
...(deps.err ? { err: deps.err } : {}),
|
|
131
|
+
...(deps.prompt ? { prompt: deps.prompt } : {}),
|
|
132
|
+
...(deps.isTTY !== undefined ? { isTTY: deps.isTTY } : {}),
|
|
133
|
+
});
|
|
134
|
+
if (!confirmed)
|
|
135
|
+
return 1;
|
|
136
|
+
const { data, error } = await s.rpc("delete_team", {
|
|
137
|
+
p_team_id: target.id,
|
|
138
|
+
p_confirm_name: confirmed,
|
|
139
|
+
});
|
|
140
|
+
if (error) {
|
|
141
|
+
errOut(`Failed to delete team: ${error.message}`);
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
const result = data[0];
|
|
145
|
+
if (!result.ok && result.code === "name_confirmation_mismatch") {
|
|
146
|
+
errOut("Server rejected confirmation (team may have been renamed). Aborted.");
|
|
147
|
+
return 1;
|
|
148
|
+
}
|
|
149
|
+
log(`Deleted team "${target.name}". ` +
|
|
150
|
+
`Removed ${JSON.stringify(result.deleted_counts)}.`);
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=teams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/commands/teams.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.whoamiCommand = whoamiCommand;
|
|
4
|
+
const auth_1 = require("../lib/auth");
|
|
5
|
+
async function whoamiCommand(opts = {}) {
|
|
6
|
+
const log = opts.log ?? ((m) => process.stdout.write(`${m}\n`));
|
|
7
|
+
const creds = await (0, auth_1.loadCredentials)();
|
|
8
|
+
if (!creds) {
|
|
9
|
+
log("Not logged in. Run `axgram login`.");
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
// Refresh-on-demand keeps the displayed identity current and proves the
|
|
13
|
+
// refresh path works on every whoami invocation.
|
|
14
|
+
const accessToken = await (0, auth_1.getActiveAccessToken)();
|
|
15
|
+
const claims = (0, auth_1.decodeJwtPayload)(accessToken);
|
|
16
|
+
const email = claims.email ?? "(no email claim)";
|
|
17
|
+
const sub = claims.sub ?? "(no sub claim)";
|
|
18
|
+
const role = claims.role ?? "authenticated";
|
|
19
|
+
const exp = typeof claims.exp === "number" ? new Date(claims.exp * 1000).toISOString() : "?";
|
|
20
|
+
log(`email: ${email}`);
|
|
21
|
+
log(`user id: ${sub}`);
|
|
22
|
+
log(`role: ${role}`);
|
|
23
|
+
log(`expires at: ${exp}`);
|
|
24
|
+
log(`supabase: ${creds.supabase_url}`);
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":";;AAMA,sCAwBC;AA9BD,sCAAsF;AAM/E,KAAK,UAAU,aAAa,CAAC,OAAsB,EAAE;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,MAAM,IAAA,sBAAe,GAAE,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,wEAAwE;IACxE,iDAAiD;IACjD,MAAM,WAAW,GAAG,MAAM,IAAA,2BAAoB,GAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAA,uBAAgB,EAAC,WAAW,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAI,MAAM,CAAC,KAA4B,IAAI,kBAAkB,CAAC;IACzE,MAAM,GAAG,GAAI,MAAM,CAAC,GAA0B,IAAI,gBAAgB,CAAC;IACnE,MAAM,IAAI,GAAI,MAAM,CAAC,IAA2B,IAAI,eAAe,CAAC;IACpE,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAE7F,GAAG,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;IAC9B,GAAG,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IAC5B,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC7B,GAAG,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IAC5B,GAAG,CAAC,iBAAiB,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.saveCredentials = saveCredentials;
|
|
4
|
+
exports.loadCredentials = loadCredentials;
|
|
5
|
+
exports.clearCredentials = clearCredentials;
|
|
6
|
+
exports.isExpired = isExpired;
|
|
7
|
+
exports.refreshCredentials = refreshCredentials;
|
|
8
|
+
exports.getActiveAccessToken = getActiveAccessToken;
|
|
9
|
+
exports.decodeJwtPayload = decodeJwtPayload;
|
|
10
|
+
const promises_1 = require("node:fs/promises");
|
|
11
|
+
const config_dir_1 = require("./config-dir");
|
|
12
|
+
const FILE_MODE = 0o600;
|
|
13
|
+
const DIR_MODE = 0o700;
|
|
14
|
+
async function saveCredentials(creds) {
|
|
15
|
+
await (0, promises_1.mkdir)((0, config_dir_1.configDir)(), { recursive: true, mode: DIR_MODE });
|
|
16
|
+
const path = (0, config_dir_1.credentialsPath)();
|
|
17
|
+
const json = JSON.stringify(creds, null, 2);
|
|
18
|
+
await (0, promises_1.writeFile)(path, json, { encoding: "utf8", mode: FILE_MODE });
|
|
19
|
+
}
|
|
20
|
+
async function loadCredentials() {
|
|
21
|
+
let raw;
|
|
22
|
+
try {
|
|
23
|
+
raw = await (0, promises_1.readFile)((0, config_dir_1.credentialsPath)(), "utf8");
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err.code === "ENOENT")
|
|
27
|
+
return null;
|
|
28
|
+
throw err;
|
|
29
|
+
}
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (typeof parsed.access_token === "string" &&
|
|
38
|
+
typeof parsed.refresh_token === "string" &&
|
|
39
|
+
typeof parsed.expires_at === "number" &&
|
|
40
|
+
typeof parsed.supabase_url === "string") {
|
|
41
|
+
return {
|
|
42
|
+
access_token: parsed.access_token,
|
|
43
|
+
refresh_token: parsed.refresh_token,
|
|
44
|
+
expires_at: parsed.expires_at,
|
|
45
|
+
supabase_url: parsed.supabase_url,
|
|
46
|
+
// Older login sessions (pre-Task 3) won't have this. Default to empty
|
|
47
|
+
// so authenticatedSupabase can detect + force a re-login with a clear
|
|
48
|
+
// error rather than silently using an unkeyed PostgREST client.
|
|
49
|
+
supabase_anon_key: typeof parsed.supabase_anon_key === "string"
|
|
50
|
+
? parsed.supabase_anon_key
|
|
51
|
+
: "",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
async function clearCredentials() {
|
|
57
|
+
await (0, promises_1.rm)((0, config_dir_1.credentialsPath)(), { force: true });
|
|
58
|
+
}
|
|
59
|
+
function isExpired(creds, skewSeconds = 60) {
|
|
60
|
+
const now = Math.floor(Date.now() / 1000);
|
|
61
|
+
return creds.expires_at - skewSeconds <= now;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Exchanges a refresh_token for a fresh access_token via Supabase Auth.
|
|
65
|
+
* Returns updated Credentials. Does not persist.
|
|
66
|
+
*/
|
|
67
|
+
async function refreshCredentials(creds, fetchImpl = fetch) {
|
|
68
|
+
const url = `${creds.supabase_url.replace(/\/+$/, "")}/auth/v1/token?grant_type=refresh_token`;
|
|
69
|
+
const res = await fetchImpl(url, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: {
|
|
72
|
+
"Content-Type": "application/json",
|
|
73
|
+
// Supabase requires the anon key as apikey for token endpoints. The
|
|
74
|
+
// CLI doesn't carry the anon key by default; the refresh endpoint
|
|
75
|
+
// accepts the access token as Bearer plus apikey echoed from the
|
|
76
|
+
// refresh token's project. We carry the anon key via env when set,
|
|
77
|
+
// otherwise omit and rely on Authorization header.
|
|
78
|
+
...(process.env.SUPABASE_PUBLISHABLE_KEY
|
|
79
|
+
? { apikey: process.env.SUPABASE_PUBLISHABLE_KEY }
|
|
80
|
+
: {}),
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify({ refresh_token: creds.refresh_token }),
|
|
83
|
+
});
|
|
84
|
+
if (!res.ok) {
|
|
85
|
+
throw new Error(`Token refresh failed: ${res.status} ${await res.text().catch(() => "")}`.trim());
|
|
86
|
+
}
|
|
87
|
+
const body = (await res.json());
|
|
88
|
+
const expires_at = typeof body.expires_at === "number"
|
|
89
|
+
? body.expires_at
|
|
90
|
+
: Math.floor(Date.now() / 1000) + (body.expires_in ?? 3600);
|
|
91
|
+
return {
|
|
92
|
+
access_token: body.access_token,
|
|
93
|
+
refresh_token: body.refresh_token,
|
|
94
|
+
expires_at,
|
|
95
|
+
supabase_url: creds.supabase_url,
|
|
96
|
+
supabase_anon_key: creds.supabase_anon_key,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Returns a non-expired access token, refreshing on disk if needed.
|
|
101
|
+
* Throws if not logged in.
|
|
102
|
+
*/
|
|
103
|
+
async function getActiveAccessToken() {
|
|
104
|
+
const creds = await loadCredentials();
|
|
105
|
+
if (!creds)
|
|
106
|
+
throw new Error("Not logged in. Run `axgram login`.");
|
|
107
|
+
if (!isExpired(creds))
|
|
108
|
+
return creds.access_token;
|
|
109
|
+
const refreshed = await refreshCredentials(creds);
|
|
110
|
+
await saveCredentials(refreshed);
|
|
111
|
+
return refreshed.access_token;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Decode a JWT payload without verifying the signature. Safe locally — the
|
|
115
|
+
* server is the source of truth for validity; we only use this for whoami
|
|
116
|
+
* display.
|
|
117
|
+
*/
|
|
118
|
+
function decodeJwtPayload(token) {
|
|
119
|
+
const parts = token.split(".");
|
|
120
|
+
if (parts.length !== 3 || !parts[1]) {
|
|
121
|
+
throw new Error("Invalid JWT format");
|
|
122
|
+
}
|
|
123
|
+
const payload = parts[1];
|
|
124
|
+
const padded = payload + "=".repeat((4 - (payload.length % 4)) % 4);
|
|
125
|
+
const decoded = Buffer.from(padded, "base64").toString("utf8");
|
|
126
|
+
return JSON.parse(decoded);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|