diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml
index 8edaae1..2a29c40 100644
--- a/.forgejo/workflows/test.yml
+++ b/.forgejo/workflows/test.yml
@@ -21,16 +21,16 @@ jobs:
playwright:
runs-on: ubuntu-latest
needs: vitest
- services:
- mongo:
- image: mongo:7
- ports:
- - 27017:27017
env:
- MONGODB_URI: mongodb://localhost:27017/ghostguild-test
+ MONGODB_URI: mongodb://mongo-ci:27017/ghostguild-test
JWT_SECRET: ci-test-jwt-secret
+ RESEND_API_KEY: re_ci_dummy_not_used
+ HELCIM_API_TOKEN: helcim_ci_dummy_not_used
+ OIDC_COOKIE_SECRET: ci-oidc-cookie-secret-not-secret
NUXT_PUBLIC_COMING_SOON: 'false'
NODE_ENV: development
+ ALLOW_DEV_TEST_ENDPOINTS: 'true'
+ BASE_URL: http://localhost:3000
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -39,15 +39,35 @@ jobs:
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
+ - name: Start MongoDB
+ run: |
+ docker rm -f mongo-ci 2>/dev/null || true
+ docker run -d --name mongo-ci mongo:7
+ # Forgejo runs each job inside its own container; attach Mongo to
+ # that container's network so MONGODB_URI=mongodb://mongo-ci:27017
+ # resolves from inside the runner.
+ RUNNER_NET=$(docker inspect "$HOSTNAME" --format '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}' | awk '{print $1}')
+ docker network connect "$RUNNER_NET" mongo-ci
+ docker ps
+ - name: Wait for MongoDB
+ run: timeout 30 sh -c 'until docker exec mongo-ci mongosh --quiet --eval "1" >/dev/null 2>&1; do sleep 1; done'
+ - name: MongoDB log on failure
+ if: failure()
+ run: docker logs mongo-ci || true
+ - name: Seed test data
+ run: node scripts/seed-all.js && node scripts/seed-tags.js
- run: npm run build
- name: Start server
- run: node .output/server/index.mjs &
+ run: node .output/server/index.mjs > /tmp/server.log 2>&1 &
env:
PORT: 3000
- name: Wait for server
run: timeout 30 sh -c 'until curl -sf http://localhost:3000; do sleep 1; done'
- - run: npx playwright test --ignore-snapshots
- - uses: actions/upload-artifact@v4
+ - name: Server log on failure
+ if: failure()
+ run: cat /tmp/server.log || true
+ - run: npx playwright test
+ - uses: actions/upload-artifact@v3
if: failure()
with:
name: playwright-report
@@ -68,39 +88,3 @@ jobs:
-H 'Content-type: application/json' \
--data "{\"text\":\":x: *Ghost Guild CI failed* on \`${{ github.ref_name }}\`\nCommit: ${{ github.sha }}\n${{ github.server_url }}/${{ github.repository }}/actions\"}"
- visual:
- runs-on: ubuntu-latest
- needs: vitest
- continue-on-error: true
- services:
- mongo:
- image: mongo:7
- ports:
- - 27017:27017
- env:
- MONGODB_URI: mongodb://localhost:27017/ghostguild-test
- JWT_SECRET: ci-test-jwt-secret
- NUXT_PUBLIC_COMING_SOON: 'false'
- NODE_ENV: development
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: 22
- cache: npm
- - run: npm ci
- - run: npx playwright install --with-deps chromium
- - run: npm run build
- - name: Start server
- run: node .output/server/index.mjs &
- env:
- PORT: 3000
- - name: Wait for server
- run: timeout 30 sh -c 'until curl -sf http://localhost:3000; do sleep 1; done'
- - run: npx playwright test e2e/visual/
- - uses: actions/upload-artifact@v4
- if: failure()
- with:
- name: visual-diffs
- path: e2e/test-results/
- retention-days: 7
diff --git a/.gitignore b/.gitignore
index 0454ac9..3907ee0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,4 @@ e2e/.auth/
.superpowers/
.claude
+scripts/dump-babyghosts-preregistrations.mjs
diff --git a/.husky/pre-push b/.husky/pre-push
old mode 100644
new mode 100755
diff --git a/.serena/project.yml b/.serena/project.yml
index 9d24cb3..0d43951 100644
--- a/.serena/project.yml
+++ b/.serena/project.yml
@@ -3,21 +3,26 @@ project_name: "ghostguild-org"
# list of languages for which language servers are started; choose from:
-# al bash clojure cpp csharp
-# csharp_omnisharp dart elixir elm erlang
-# fortran fsharp go groovy haskell
-# java julia kotlin lua markdown
-# matlab nix pascal perl php
-# php_phpactor powershell python python_jedi r
-# rego ruby ruby_solargraph rust scala
-# swift terraform toml typescript typescript_vts
-# vue yaml zig
+# al angular ansible bash clojure
+# cpp cpp_ccls crystal csharp csharp_omnisharp
+# dart elixir elm erlang fortran
+# fsharp go groovy haskell haxe
+# hlsl html java json julia
+# kotlin lean4 lua luau markdown
+# matlab msl nix ocaml pascal
+# perl php php_phpactor powershell python
+# python_jedi python_ty r rego ruby
+# ruby_solargraph rust scala scss solidity
+# swift systemverilog terraform toml typescript
+# typescript_vts vue yaml zig
# (This list may be outdated. For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
+# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root)
+# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three)
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# Some languages require additional setup/installations.
@@ -65,53 +70,17 @@ read_only: false
# list of tool names to exclude.
# This extends the existing exclusions (e.g. from the global configuration)
-#
-# Below is the complete list of tools for convenience.
-# To make sure you have the latest list of tools, and to view their descriptions,
-# execute `uv run scripts/print_tool_overview.py`.
-#
-# * `activate_project`: Activates a project by name.
-# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
-# * `create_text_file`: Creates/overwrites a file in the project directory.
-# * `delete_lines`: Deletes a range of lines within a file.
-# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
-# * `execute_shell_command`: Executes a shell command.
-# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
-# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
-# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
-# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
-# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
-# * `initial_instructions`: Gets the initial instructions for the current project.
-# Should only be used in settings where the system prompt cannot be set,
-# e.g. in clients you have no control over, like Claude Desktop.
-# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
-# * `insert_at_line`: Inserts content at a given line in a file.
-# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
-# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
-# * `list_memories`: Lists memories in Serena's project-specific memory store.
-# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
-# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
-# * `read_file`: Reads a file within the project directory.
-# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
-# * `remove_project`: Removes a project from the Serena configuration.
-# * `replace_lines`: Replaces a range of lines within a file with new content.
-# * `replace_symbol_body`: Replaces the full definition of a symbol.
-# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
-# * `search_for_pattern`: Performs a search for a pattern in the project.
-# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
-# * `switch_modes`: Activates modes by providing a list of their names
-# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
-# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
-# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
-# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
+# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
# This extends the existing inclusions (e.g. from the global configuration).
+# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
included_optional_tools: []
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
+# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
fixed_tools: []
# list of mode names to that are always to be included in the set of active modes
@@ -122,11 +91,14 @@ fixed_tools: []
# Set this to a list of mode names to always include the respective modes for this project.
base_modes:
-# list of mode names that are to be activated by default.
-# The full set of modes to be activated is base_modes + default_modes.
-# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
+# list of mode names that are to be activated by default, overriding the setting in the global configuration.
+# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
+# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
+# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply
+# for this project.
# This setting can, in turn, be overridden by CLI parameters (--mode).
+# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
default_modes:
# initial prompt for the project. It will always be given to the LLM upon activating the project
@@ -150,3 +122,19 @@ read_only_memory_patterns: []
# Extends the list from the global configuration, merging the two lists.
# Example: ["_archive/.*", "_episodes/.*"]
ignored_memory_patterns: []
+
+# list of mode names to be activated additionally for this project, e.g. ["query-projects"]
+# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
+# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
+added_modes:
+
+# list of additional workspace folder paths for cross-package reference support (e.g. in monorepos).
+# Paths can be absolute or relative to the project root.
+# Each folder is registered as an LSP workspace folder, enabling language servers to discover
+# symbols and references across package boundaries.
+# Currently supported for: TypeScript.
+# Example:
+# additional_workspace_folders:
+# - ../sibling-package
+# - ../shared-lib
+additional_workspace_folders: []
diff --git a/Dockerfile b/Dockerfile
index 54b1438..0375bac 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build stage
-FROM node:20-alpine AS builder
+FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
@@ -7,8 +7,11 @@ RUN npm ci --ignore-scripts && npx nuxt prepare
COPY . .
RUN npm run build
-# Production stage — only the self-contained .output is needed
-FROM node:20-alpine
+# Production stage — only the self-contained .output is needed.
+# bash + curl are added so Dokploy scheduled tasks (which wrap commands in
+# `bash -c "..."`) can run; alpine ships only ash and has no curl by default.
+FROM node:22-alpine
+RUN apk add --no-cache bash curl
WORKDIR /app
COPY --from=builder /app/.output .output
diff --git a/app/assets/css/main.css b/app/assets/css/main.css
index 4b39e60..9ee189f 100644
--- a/app/assets/css/main.css
+++ b/app/assets/css/main.css
@@ -27,7 +27,10 @@
--text: #2a2015;
--text-bright: #1a1008;
--text-dim: #5a5040;
- --text-faint: #746a58;
+ /* Darkened from #746a58 (4.01:1 on --surface, fails WCAG AA) to #665c4b
+ (4.94:1 on --surface, 5.13:1 on --bg). Stays visually quieter than
+ --text-dim (5.80:1) while meeting AA for small text. */
+ --text-faint: #665c4b;
--parch: #2a2015;
--parch-hover: #3a3025;
--parch-text: #ede4d0;
@@ -273,6 +276,14 @@ p a, blockquote a {
min-width: 0;
}
+/* ---- Nuxt UI placeholder contrast ----
+ Default Nuxt UI placeholder uses `text-dimmed` (#a6a09b) which fails WCAG
+ AA on cream and white backgrounds (≈2.4:1). Override globally to --text-dim
+ so USelect/USelectMenu placeholders meet the 4.5:1 ratio. */
+[data-slot="placeholder"] {
+ color: var(--text-dim);
+}
+
/* ---- SHARED USelectMenu STYLES ----
Apply via:
+ → {{ previewText }} +
++ {{ errorMessage }} +
{{ error }}
+{{ error }}
By registering, you'll be automatically registered for all {{ seriesInfo.totalEvents }} events in this series. + We'll create a free guest account so you can access your pass.
- We've sent a confirmation email to {{ summary?.email }}. Redirecting - you to your dashboard... + Check {{ summary?.email }} for a sign-in link to finish setting up + your account. The link expires in 15 minutes.
- @@ -113,7 +108,7 @@ const stepLabel = computed(() => { position: fixed; inset: 0; z-index: 50; - background: rgba(42, 32, 21, 0.72); + background: color-mix(in srgb, var(--parch) 72%, transparent); backdrop-filter: blur(4px); display: flex; align-items: center; diff --git a/app/components/TierPicker.vue b/app/components/TierPicker.vue deleted file mode 100644 index 5cf6318..0000000 --- a/app/components/TierPicker.vue +++ /dev/null @@ -1,99 +0,0 @@ - -{{ event.description }}
+{{ event.series.description }}
+ +- Baby Ghosts Studio Development Fund is a registered Canadian charity. - Members who file Canadian taxes can claim their contributions. - We'll help you set up tax receipts once you've joined. + Baby Ghosts Studio Development Fund is a registered Canadian + charity. Members who file Canadian taxes can claim their + contributions. We'll help you set up tax receipts once you've + joined.
Pay what you can. If you can pay more, you're making room for @@ -118,7 +129,7 @@ type="text" placeholder="Your name" required - > + />
{{ guidanceLabel }}
++ {{ guidanceLabel }} +
- You'll be charged ${{ firstCharge }} today (${{ form.contributionAmount }}/month × 12). + You'll be charged ${{ firstCharge }} today + (${{ form.contributionAmount }}/month × 12).
- Then ${{ firstCharge }} every {{ cadence === 'annual' ? 'year' : 'month' }}, until you cancel. + Then + ${{ firstCharge }} every + {{ cadence === "annual" ? "year" : "month" }}, until you cancel.
+ Community connection happens in our Slack workspace, joined in monthly + onboarding waves — there may be a short wait after you join. +
@@ -338,12 +363,11 @@For those already running cooperative studios or with deep - experience in cooperative practice. You are here to teach, advise, - mentor, and help shape the program itself. Alumni. + experience in cooperative practice. You're here to support newcomers + and help shape the Cooperative Foundations program.
{{ series.description }}
-{{ series.description }}
+{{ event.description }}
+No sessions scheduled yet.
+No sessions scheduled yet.
-Loading series...
+
+ No series right now. Check back later or browse
+
+ {{ series.description }} +
- {{ series.description }} -
-
- Check back later or browse
-