From 4093c5e031bfc6d36556f6a3553bf717cdc074c0 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Mon, 16 Mar 2026 19:12:44 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20DRY=20getValidToken=20=E2=80=94=20cli-te?= =?UTF-8?q?am=20delegates=20to=20sync.ts,=20remove=20phantom=20Joined=20co?= =?UTF-8?q?lumn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Export getValidToken from sync.ts (was private) - cli-team.ts now uses sync.ts version (supports auto-refresh, was missing) - Remove unused isTokenExpired/getAuthTokens imports from cli-team - Remove "Joined" column from formatMembersTable (team_members has no created_at) Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/cli-team.ts | 37 +++++++++++++------------------------ lib/sync.ts | 2 +- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/lib/cli-team.ts b/lib/cli-team.ts index 5692d2b1..85e9b8cd 100644 --- a/lib/cli-team.ts +++ b/lib/cli-team.ts @@ -8,9 +8,8 @@ * set Set a team setting (admin-only) */ -import { resolveSyncConfig, isSyncConfigured, getTeamConfig, getAuthTokens } from './sync-config'; -import { pullTable } from './sync'; -import { isTokenExpired } from './auth'; +import { resolveSyncConfig, isSyncConfigured } from './sync-config'; +import { pullTable, getValidToken as getValidTokenFromSync } from './sync'; // --- Types --- @@ -22,24 +21,17 @@ interface TeamMember { // --- Helpers --- -async function getValidToken(): Promise<{ token: string; config: ReturnType } | null> { +async function getValidTokenAndConfig(): Promise<{ token: string; config: ReturnType } | null> { const config = resolveSyncConfig(); if (!config) { console.error('Team sync not configured. Run: gstack sync setup'); return null; } - - const token = config.auth.access_token; + const token = await getValidTokenFromSync(config); if (!token) { - console.error('Not authenticated. Run: gstack sync setup'); + console.error('Not authenticated or token expired. Run: gstack sync setup'); return null; } - - if (config.auth.expires_at && isTokenExpired(config.auth.expires_at)) { - console.error('Auth token expired. Run: gstack sync setup'); - return null; - } - return { token, config }; } @@ -128,24 +120,21 @@ export function formatMembersTable(members: Record[]): string { const lines: string[] = []; lines.push(''); lines.push('Team Members'); - lines.push('═'.repeat(60)); + lines.push('═'.repeat(50)); lines.push( ' ' + 'Email / User ID'.padEnd(35) + - 'Role'.padEnd(12) + - 'Joined' + 'Role' ); - lines.push('─'.repeat(60)); + lines.push('─'.repeat(50)); for (const m of members) { const who = String(m.email || m.user_id || 'unknown').slice(0, 33).padEnd(35); - const role = String(m.role || 'member').padEnd(12); - // team_members doesn't have created_at, so use a placeholder - const joined = '—'; - lines.push(` ${who}${role}${joined}`); + const role = String(m.role || 'member'); + lines.push(` ${who}${role}`); } - lines.push('─'.repeat(60)); + lines.push('─'.repeat(50)); lines.push(` ${members.length} member${members.length === 1 ? '' : 's'}`); lines.push(''); return lines.join('\n'); @@ -154,7 +143,7 @@ export function formatMembersTable(members: Record[]): string { // --- Subcommands --- async function cmdCreate(slug: string, name: string): Promise { - const auth = await getValidToken(); + const auth = await getValidTokenAndConfig(); if (!auth) return; const { config } = auth; @@ -195,7 +184,7 @@ async function cmdMembers(): Promise { } async function cmdSet(key: string, value: string): Promise { - const auth = await getValidToken(); + const auth = await getValidTokenAndConfig(); if (!auth) return; const { config } = auth; diff --git a/lib/sync.ts b/lib/sync.ts index 72e63c2b..af3660d6 100644 --- a/lib/sync.ts +++ b/lib/sync.ts @@ -67,7 +67,7 @@ async function refreshToken(supabaseUrl: string, refreshToken: string, anonKey: } /** Get a valid access token, refreshing if needed. */ -async function getValidToken(config: SyncConfig): Promise { +export async function getValidToken(config: SyncConfig): Promise { if (!isTokenExpired(config.auth)) { return config.auth.access_token; }