Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
26bad2c
chore: start the rewrite, initial commands and events in place
alexthemaster Dec 29, 2025
f1a17f6
docs: yodate discord token url and example env location
alexthemaster Dec 29, 2025
c1e9785
fix(command): make description optional
alexthemaster Dec 29, 2025
4b65bbb
feat(commands): add ownerOnly property
alexthemaster Dec 30, 2025
b4e7b72
feat(ping): use ms for time
alexthemaster Dec 30, 2025
da962a0
feat(commands): add exec
alexthemaster Dec 30, 2025
26ac063
fix(exec): send as file if output too large
alexthemaster Dec 30, 2025
8732264
feat(commands): add eval
alexthemaster Dec 30, 2025
b9adc3b
docs(example.env): replace admin with other
alexthemaster Dec 30, 2025
8f27aa9
feat(commands): add lyrics
alexthemaster Dec 30, 2025
84b9693
feat(commands): add cooldown and fix lyrics error
alexthemaster Dec 30, 2025
355199c
refactor: move owner populating to ready event
alexthemaster Dec 30, 2025
bea93bc
feat(db): implement prisma
alexthemaster Dec 30, 2025
78ffc9f
fix: properly push single owner id
alexthemaster Dec 30, 2025
639f905
feat(settings): implement basic listing and setting
alexthemaster Dec 30, 2025
1b1352f
fix(settings): use BigInt instead of Number for id
alexthemaster Dec 30, 2025
7e553b6
feat: add reminders
alexthemaster Dec 30, 2025
e1d6664
fix(reminder): check for negatives in regular string, not just date
alexthemaster Dec 30, 2025
d55615c
build(npm): add prisma:init script
alexthemaster Dec 30, 2025
b17eff5
docs: add note about legacy branch
alexthemaster Dec 30, 2025
4964131
fix(reminder): i *sneezed* on my keyboard
alexthemaster Dec 30, 2025
5b93f30
feat(stats): add penfoldbot version
alexthemaster Dec 31, 2025
157600b
feat(settings): add toggle for daily dms
alexthemaster Dec 31, 2025
41344bf
fix(settings): make epheral
alexthemaster Dec 31, 2025
998d79d
feat: add eslint
alexthemaster Dec 31, 2025
3b8d82f
build: add prettier
alexthemaster Dec 31, 2025
0ec4b15
ci: add continuous integration
alexthemaster Dec 31, 2025
a7c26bc
fix: ci linting
alexthemaster Dec 31, 2025
14533fa
fix(ci): generate prisma client to be able to build the code
alexthemaster Dec 31, 2025
d1a5ce1
feat(settings/timezone): add autocomplete
alexthemaster Dec 31, 2025
ce423aa
feat(reminders): add snooze buttons to message
alexthemaster Dec 31, 2025
67bc140
feat(reminders): fire them at a more precise time
alexthemaster Jan 2, 2026
cf4abc8
feat(reminders): change snooze times
alexthemaster Jan 2, 2026
59ce651
fix(reminders): make sure to filter out reminders that will be fired now
alexthemaster Jan 2, 2026
fae3b48
fix(reminders): use correct settimeout time
alexthemaster Jan 2, 2026
447ddb7
fix(reminders): use Math.abs on settimeout
alexthemaster Jan 2, 2026
185f516
feat(reminders): fire task after creating reminder to handle very sho…
alexthemaster Jan 2, 2026
e92df38
feat(tasks): add clientReady property
alexthemaster Jan 2, 2026
ab1ff51
fix(task/reminder): only run if client is ready
alexthemaster Jan 2, 2026
1e1b910
fix(penfoldclient/debug): allow multiple args
alexthemaster Jan 2, 2026
bbf70a8
feat(settings/dailydmtime): implement parsing and validation
alexthemaster Jan 2, 2026
c01a5f3
feat: add dailydm functionality
alexthemaster Jan 2, 2026
1877ed4
feat: add todos
alexthemaster Jan 2, 2026
3e20454
fix(todo): typo
alexthemaster Jan 2, 2026
b222d99
chore(events/ready): only mention guilds
alexthemaster Jan 2, 2026
5761583
fix: make sure long embeds don't crash
alexthemaster Jan 2, 2026
9f76ecd
feat: add notes
alexthemaster Jan 2, 2026
1302e9e
feat(todo): add search functionality
alexthemaster Jan 2, 2026
c6cba0a
chore(db): remove notes from reminders
alexthemaster Jan 2, 2026
391bb01
feat: add action command
alexthemaster Jan 3, 2026
ffab35c
feat(reminders): implement a collection based queue instead of writin…
alexthemaster Jan 3, 2026
adc709d
fix(notes): typo from copy-pasting
alexthemaster Jan 3, 2026
3f0f60f
feat: add i18n localization
alexthemaster Jan 4, 2026
c9b967b
style(commands/assistant): format code
alexthemaster Jan 4, 2026
0dc7674
Update Crowdin configuration file
alexthemaster Jan 4, 2026
6c3653e
Update Crowdin configuration file
alexthemaster Jan 4, 2026
b5543ab
docs: add crowdin badge to readme
alexthemaster Jan 4, 2026
0eb9d97
Merge branch 'rewrite' of https://github.com/penfoldium/penfoldbot in…
alexthemaster Jan 4, 2026
f2539a7
fix(commands.json): typo in cooldown
alexthemaster Jan 4, 2026
caefdc3
fix(commands.json): attacked typo
alexthemaster Jan 4, 2026
1322b2b
chore: make crowdin commit using conventional commits
alexthemaster Jan 4, 2026
5db0c63
chore: format crowdin.yml so prettier doesn't fail
alexthemaster Jan 4, 2026
1bcf295
chore: update crowdin commit message
alexthemaster Jan 5, 2026
167b621
ci(translations): replace gh integration with gh actions
alexthemaster Jan 5, 2026
fcbd1e9
style: format workflows
alexthemaster Jan 5, 2026
56ccfee
feat(utilities): add appstore
alexthemaster Jan 5, 2026
9c62d7d
feat(utilities/appstore): add mb to size
alexthemaster Jan 5, 2026
a5fd88c
feat: move dayjs and i18n setup to separate file
alexthemaster Jan 5, 2026
f5d8bb6
feat(util): export commands to json
alexthemaster Jan 5, 2026
32fbf44
feat(exportcommands): don't include owneronly
alexthemaster Jan 5, 2026
b5a6f6b
build: add generatejson script
alexthemaster Jan 5, 2026
3027cdf
fix(penfoldclient): load classes on linux (case sensitive)
alexthemaster Jan 6, 2026
aadfe19
fix: accidentally pushed commands.json
alexthemaster Jan 6, 2026
35945ed
docs: prisma comes first, then building
alexthemaster Jan 6, 2026
7457475
feat(utilities): add rot13, atbash and base64
alexthemaster Jan 6, 2026
020142c
feat(utilities): wikipedia search
alexthemaster Jan 6, 2026
317a515
refactor(utilities); use this.stringOption where applicable
alexthemaster Jan 6, 2026
06ddd2d
chore: rename admin folder to owner
alexthemaster Jan 6, 2026
7bd0d71
docs(readme): remove optional stuff
alexthemaster Jan 6, 2026
9b63954
feat(reminders): send to channel too
alexthemaster Jan 6, 2026
1f48557
feat(reminders): add localization
alexthemaster Jan 6, 2026
73f9798
chore(db): merge all migrations into one
alexthemaster Jan 6, 2026
884155e
feat: ensure user settings at every interaction
alexthemaster Jan 6, 2026
0f4992d
fix(reminders): forgot to replace test string
alexthemaster Jan 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
31 changes: 31 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "Continuous Integration"

on: [push]

jobs:
build:
name: Check linting, formatting and building of the code
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "lts/*"

- name: Install dependencies
run: npm ci

- name: Check code linting
run: npm run lint

- name: Check code formatting
run: npm run format:check

- name: Generate Prisma client to be able to build code
run: DATABASE_URL=file:./db/penfold-ci-github.sqlite npm run prisma:init
- name: Check if code builds
run: npm run build
32 changes: 32 additions & 0 deletions .github/workflows/crowdin-download.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Crowdin Sync Translations

on:
schedule:
- cron: "0 */12 * * *"
workflow_dispatch:

permissions: write-all

jobs:
crowdin-sync-translations:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: crowdin action
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
localization_branch_name: l10n_crowdin_translations
create_pull_request: true
pull_request_title: "New Translations"
pull_request_body: "New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)"
pull_request_base_branch_name: "rewrite"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
24 changes: 24 additions & 0 deletions .github/workflows/crowdin-upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Crowdin Upload Sources

on:
push:
paths: ["src/Locales/**"]
branches: [rewrite]

jobs:
crowdin-upload:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Crowdin push
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: true
download_translations: false
env:
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
name: Crowdin Action
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
src/bwd
node_modules
src/data/config.json
*.env
!example.env
dist
db/*
!db/schema.prisma
!db/migrations
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"trailingComma": "none",
"printWidth": 100,
"arrowParens": "avoid"
}
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019-2022 Penfoldium
Copyright (c) 2019-2026 Penfoldium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
8 changes: 8 additions & 0 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
files:
- source: /src/Locales/en-US/*
translation: /src/Locales/%two_letters_code%/%original_file_name%
commit_message: "feat(translations): update %language% (%original_file_name%) from crowdin"
append_commit_message: false
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_PERSONAL_TOKEN
base_path: .
45 changes: 45 additions & 0 deletions db/migrations/20260106215006_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- CreateTable
CREATE TABLE "UserSettings" (
"id" BIGINT NOT NULL PRIMARY KEY,
"timezone" TEXT NOT NULL DEFAULT 'Etc/UTC',
"dailyDmTime" TEXT NOT NULL DEFAULT '8:00',
"dailyDmEnabled" BOOLEAN NOT NULL DEFAULT true
);

-- CreateTable
CREATE TABLE "Reminders" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"user_id" BIGINT NOT NULL,
"channel_id" BIGINT,
"locale" TEXT NOT NULL,
"date" DATETIME NOT NULL,
"message" TEXT NOT NULL,
"triggered" BOOLEAN NOT NULL
);

-- CreateTable
CREATE TABLE "Todos" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"user_id" BIGINT NOT NULL,
"todo" TEXT NOT NULL,
"completed" BOOLEAN NOT NULL
);

-- CreateTable
CREATE TABLE "Notes" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"user_id" BIGINT NOT NULL,
"note" TEXT NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "UserSettings_id_key" ON "UserSettings"("id");

-- CreateIndex
CREATE UNIQUE INDEX "Reminders_id_key" ON "Reminders"("id");

-- CreateIndex
CREATE UNIQUE INDEX "Todos_id_key" ON "Todos"("id");

-- CreateIndex
CREATE UNIQUE INDEX "Notes_id_key" ON "Notes"("id");
3 changes: 3 additions & 0 deletions db/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"
41 changes: 41 additions & 0 deletions db/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client"
output = "./prisma"
}

datasource db {
provider = "sqlite"
}

model UserSettings {
id BigInt @id @unique
timezone String @default("Etc/UTC")
dailyDmTime String @default("8:00")
dailyDmEnabled Boolean @default(true)
}

model Reminders {
id Int @id @unique @default(autoincrement())
user_id BigInt
channel_id BigInt?
locale String
date DateTime
message String
triggered Boolean
}

model Todos {
id Int @id @unique @default(autoincrement())
user_id BigInt
todo String
completed Boolean
}

model Notes {
id Int @id @unique @default(autoincrement())
user_id BigInt
note String
}
13 changes: 13 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @ts-check

import eslint from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier/flat";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";

export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommended,
eslintConfigPrettier,
globalIgnores(["./src/Examples/*", "./dist/**/*"])
);
10 changes: 10 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# If true, it will only register slash commands to specified guild ID instead of globally (useful when adding/removing/modifying commands)
DEV=false
# If true, will provide additional logs to console
DEBUG=false
# Optional, needed if DEV=true or for owner only commands
GUILD_ID=
TOKEN=
DATABASE_URL=file:./db/penfold.sqlite
# Default language for console logs
LANGUAGE=en
Loading