The two limits were compiled in: a task run stopped at
AppData.HarnessMaxToolSteps (200) and a chat reply at
AppData.BotReplyMaxToolSteps (8), so an install that needed a longer task
had to rebuild.
Both are now `app_settings` rows (`harness_max_tool_steps` and
`bot_reply_max_tool_steps`), read at the two loop call sites through
grabHarnessMaxToolSteps and grabReplyMaxToolSteps, and edited by the super
admin on Settings > General beside the prompt appendix. Zero clears a
limit back to the code default, like the bot file quota.
readStepLimit keeps the saved number only when it is a whole number of at
least 1 and no more than AppData.BotStepLimitMax (1000), so a blank, a
zero or a typo falls back instead of stopping every run before its first
turn, and a huge number still ends in the wrap-up report.
runTextLoop keeps AppData.HarnessMaxToolSteps as its default, so it stays
free of database reads and its tests run as they did.
The General page ends with a Version block naming the release this
server runs, so an update can be confirmed from the app.
The version is COBBLE_VERSION, the release tag the image was built with
(Dockerfile ARG, passed by the release workflow, which falls back to
package.json's version on a workflow-dispatch build), else package.json's
version, which a development server reports too, with (development)
after it. runningVersion (src/utils/running-version.ts) drops an
unusable version string rather than showing it.
Also includes the working tree's pending signup guard in
src/pages/__root.server.ts: a user who still holds a session while the
install has no users is sent to /auth/logout (and may load it).
Settings > General gains a prompt appendix the super admin sets once:
markdown every bot runs with, right after its own core instructions.
- The text lives in app_settings (bot_system_prompt_append, read through
grabSystemPromptAppend, cached like every app setting), so it changes
without a deploy and applies to every bot on the next run.
- composeBotPrompt takes an appendix and pushes it as
# Install-wide instructions directly after system_prompt, before the
workspace block and memory, so the bot's own more specific rules still
win. grabBotPrompt feeds it in, so chat replies, tasks, scheduled runs
and the coordinator all get it with no call site touched.
- api/admin/settings/system-prompt-append saves it (super admin only,
capped at AppData.PromptMaxLength, empty clears it) and is audit
logged under system.
- The section and its form are hidden from everyone but the super admin,
save in place with a character count and no reload, and say what an
empty text does.
Local, password-only auth:
- No public pages; everything outside /admin and /auth redirects in
- First run (no users) sends every page to /auth/signup, which creates
the super admin (user #1) once and then locks
- Login is email/username + password; removed the emailed-code flow,
/auth/sso and email password reset
- Google login kept for existing accounts only, never creates them
- seed-super-admin now requires SEED_SUPER_ADMIN_PASSWORD
Bots-first admin:
- /admin and closed sections (people, logs, backups) redirect to
/admin/bots; only bots and settings are live (AdminSections)
- Removed the old admin layout; every /admin page uses the bots rail
- Coordinator bot created at signup/seed and by /admin/bots
(ensureCoordinatorBot), which redirects to its chat
- bots.system_prompt (markdown) with a default coordinator prompt
- seed-bots reuses the existing coordinator
Settings:
- Sub pages general (default), profile, change-password, listed in the
rail with a back link; unknown settings paths redirect to general
- Redesigned settings UI: pane header, grouped rows, sticky save bar
- General: System/Light/Dark theme, saved per device
Co-Authored-By: Claude Opus 5.5 <[email protected]>