Repository navigation
Releases: spacesdrive/twiligent
Release list
v1.2.0 - Versioned database migrations and a database that guards its data
Twiligent's database is now managed with versioned migrations, and the database itself enforces who owns what and which values are valid. This release also closes two security holes and makes CI and deploys more reliable.
Added
- Versioned database migrations in
supabase/migrations/, one table or one function per file, each with a rollback insupabase/rollbacks/ npm run db:status,db:checkanddb:pushto see, preview and apply migrations, andnpm run db:newto start a new one
Changed
- The database refuses values the app never writes, such as an unknown platform or post status
- Every table keeps an
updated_attime - Removing an account also removes its scheduled posts; tracked items stay and lose only the account
- Lists load from indexes that match their order, and new rows get random ids that cannot be guessed
Fixed
- Security: a signed-in member could read their stored Instagram tokens and Reddit cookies, and write rows, directly through Supabase's public API. The tables are now closed to the browser.
- Security: a scheduled post could name another member's Instagram account, and the scheduler would publish to it. A post can now only use your own Instagram account.
- A token refresh and an analytics refresh at the same moment no longer put an old Instagram token back.
- Accounts are listed in the order they were added, the same on every load.
- CI and deploys no longer fail when npm skips a platform binary during the install.
- Dependencies with known vulnerabilities are updated, including hono in the Worker and react-router in the app and the site.
Upgrading
If you run your own Twiligent, apply the migrations before you deploy this version:
npm ci
npx supabase login
npx supabase link --project-ref <your-project-id>
npm run db:check
npm run db:pushThe first migrations describe the tables as they were and are safe on an existing database, so they bring any earlier setup to the same starting point. If a check stops the push because of an old row, the error names the rule; fix that row in the Table Editor and run npm run db:push again. Building the Worker now uses Wrangler 4, which needs Node 22 or newer. The same steps are in Upgrading an existing instance.
Full list of changes: CHANGELOG.md
v1.1.1 - Docs home fix and scheduler recovery
Scheduled Instagram posts now recover when a publishing run stops partway, and a post that reached Instagram is never marked failed or published twice. This release also fixes the empty docs home page.
Fixed
- A scheduled post no longer stays in Publishing when a run stops partway. The next run takes it over after 20 minutes.
- A post that reached Instagram is no longer marked failed when Instagram's reply is lost. Before deciding, the scheduler asks Instagram whether the post went out, so it is never published twice.
- A timeout or a temporary Instagram error no longer fails a post at once. The post is tried again on the next two runs, and its row shows "Trying again on the next run".
- Deleting or editing a post can no longer change one that is being published.
- The overdue alert in Publish also warns about posts stuck in Publishing.
- The docs home at https://twiligent.ujjwal.fyi/docs shows the Introduction page again.
Changed
- The GitHub Actions backup runs at minutes 7, 22, 37 and 52, one run at a time, with a 14 minute limit. GitHub often starts these runs hours late, so the app and the docs no longer promise 15 minutes for it. The server's own scheduler still publishes within 15 minutes.
Upgrading
If you run your own Twiligent, run this SQL in the Supabase SQL editor before you deploy this version. It adds two columns and two indexes to scheduled_posts, and marks posts that were stuck in Publishing as failed, with a note to check Instagram before scheduling them again.
alter table public.scheduled_posts
add column if not exists claimed_at timestamptz,
add column if not exists attempts integer not null default 0;
update public.scheduled_posts
set status = 'failed',
data = data || jsonb_build_object('error', 'Publishing was interrupted before Twiligent tracked it. Check Instagram before scheduling this post again.')
where status = 'publishing' and claimed_at is null;
create index if not exists scheduled_posts_user_id_idx on public.scheduled_posts (user_id);
create index if not exists scheduled_posts_due_idx on public.scheduled_posts (status, scheduled_at);The same SQL is in Upgrading an existing instance.
Full list of changes: CHANGELOG.md
v1.1.0 - Public site and docs, new sign-in, app on its own address
Twiligent now has a public website and docs, a new sign-in page that starts with Google or an emailed code, and a redesigned interface in the Twiligent brand.
Added
- A public website and docs at https://twiligent.ujjwal.fyi, with docs search (Ctrl K) and light and dark themes
- Sign in with Google, and sign in with a 6-digit code sent by email
- Passwords for every account: set or change one in Settings, and reset a forgotten one with an emailed code
- Rate limits on every API request, with a message that says when to try again
Changed
- The sign-in page is one card over a picture of the dashboard. It starts with Google or an email address, and Use password keeps email and password sign-in
- Every page is rebuilt on shared components in the Twiligent brand, in light and dark themes
- The app runs at https://app.twiligent.ujjwal.fyi, and its old links on twiligent.ujjwal.fyi redirect there
- Every failed request answers with one error shape and a request id to quote
- The whole project is TypeScript in strict mode
Fixed
- The Worker cron and the GitHub Actions backup can no longer publish the same scheduled post twice
- YouTube likes and comments the owner hid show as Hidden instead of 0
- Channels with no public videos open with a message instead of failing
- Overview no longer shows "Syncing analytics" forever
- Cached analytics refresh after 6 hours instead of never expiring
- Stored account secrets no longer appear in the comparison response
Upgrading
If you run your own Twiligent:
- The Worker's
FRONTEND_URLandALLOWED_ORIGINS, the Supabase Auth URLs and the Google sign-in origins must name the address your app is served from. - Email codes need the Send Email hook and the optional Worker secrets
SEND_EMAIL_HOOK_SECRET,RESEND_API_KEY,EMAIL_FROMandEMAIL_DAILY_LIMIT. Without them, Supabase's own email signs people in with a link. See Email codes. - Google sign-in shows only when
VITE_GOOGLE_CLIENT_IDis set. See Google sign-in.
Full list of changes: CHANGELOG.md