- Messages: the message list now scrolls inside a fixed-height pane instead of
growing the page; new messages autoscroll only when already at the bottom,
and scrolling near the top loads older history (40 at a time) with the
position preserved.
- Add a message search box in the conversations sidebar backed by a new
GET /api/v1/messages/search endpoint (searches the caller's conversations,
returns snippets); clicking a result opens that conversation.
- Manage-members dialog no longer grows horizontally: results are stacked in a
fixed-width, scrollable list.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Audit log: backend only returns a next cursor when the page is full, so the
"Load more" button no longer needs two clicks (and hides at the last page).
Table now spans the full screen width and long detail JSON wraps instead of
overflowing.
- Bounty board: pin each card's action row to the bottom so "Request
assignment" lines up across equal-height cards.
- Light theme: restore the Y2K dither texture on the sidebar nav panel.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bright dither dots created visual noise behind sidebar menu items on the
dark themes. Dark/neon/blueprint/sunset now use a low-contrast dot a touch
above their background on a sparser 8px tile. Terminal swaps dots for faint
horizontal scanlines (1×3 tile) for an interlaced CRT look.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sidebar/top-bar links used --muted, which was too dim against the dark
surfaces of the neon/dark/terminal themes. Mix 72% --text so menu items stay
legible everywhere while inactive links remain softer than headings.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Navigation: new per-user setting (default "side") renders the page links as a
left sidebar while keeping theme/bell/avatar/logout in the top-right; falls
back to a top bar under 760px or when set to "top". Profile selector added.
- Group conversations: record a creatorId; the creator gets a "Manage members"
button to add/remove participants (new GET/POST/DELETE members endpoints,
creator-only). Existing groups backfilled.
- Customer ticketing: admin can map each assigned consultant to their username
in that customer's ticketing system. Per-customer mapping takes precedence
over the consultant's global ticketingIdentities during sync.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Themes: add neon (cyber gradient), terminal (green CRT), blueprint (graph
paper) and sunset (vaporwave) alongside the default Light (Y2K paper) and
Dark. Theme toggle now cycles all; profile selector lists them; server
validates against a shared whitelist.
- Bounty cards now show the project (customer) name.
- Remove the celebratory emoji from the empty Review Queue.
- Full-width h1 underline rule; My Tasks columns stack vertically for more
room per task; card action buttons wrap/right-align so they never overflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Board visibility (§4.4): developers now see tasks for any customer with a
consultant who pooled them, not only tasks whose consultantId is in their
pool. Fixes a published task being invisible to its own author who is both
consultant and developer. Adds TestBoardVisibilityIsCustomerBased.
- Chat widget: working ✕ close, distinct (non-ghost) header buttons, reliable
conversation switching, ← Back, title ellipsis.
- Atomization: atomized/imported subtasks now expose a Subdivide button.
- Static assets: serve with ETag + Cache-Control: no-cache so JS/CSS fixes
reach clients immediately instead of being masked by stale max-age caching.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- theme rework (user request): white paper bg, brown ink, ordered-dither
halftone textures, hard offset Y2K shadows, dithered masthead bands;
dark theme matched; token test + DECISIONS updated
- fix: .card + .card stacking margin leaked into grid layouts, shifting
every card except the first (the 'always the first item' reports)
- fix: CSP style-src 'self' silently dropped every inline style attribute
(misaligned save button, stat values, editor attach button, bell badge);
styles now allow inline, scripts remain strict per §12
- fix: [hidden] is now display:none !important so flex containers cannot
defeat it (chat panel/footers)
- board + metrics filters live in boxed .toolbar rows with baseline-aligned
controls; metric stat cards use a uniform .stat layout
- new-conversation dialog: fixed 440px width and 180px results list (no
more resizing while searching), full-width result rows, picked people
drop out of the list
- floating messages bubble bottom-right on all pages (except /messages):
unread badge, mini panel with conversation list, thread view, quick
composer, live WS updates; toasts moved up to clear it
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- live testing against a real WeKan v9.36 found that the driver decodes
nested extra.ticketingIdentities as bson.D, so identity lookups silently
returned empty and consultants were skipped; handle bson.D/bson.M/map
- integration regression test pinning the BSON round trip
- opt-in live test (go test -tags=wekanlive) verifying TestConnection,
FetchUpdated (assignee + member fallback), key listing, since-filter and
unknown-identity rejection against a real instance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- APP_INTERNAL_URL: in-network base URL for §5.2 callbacks and signed
attachment URLs handed to the external services (compose: http://app:8787)
- work-performer image runs as the node user with ~/.claude mounted into
/home/node — the claude CLI refuses --dangerously-skip-permissions as root
- scripts/acceptance.sh: re-run-safe live verification of the §13 checklist
(demo import within one poll, subdivide sum=1 + editable, extend sibling,
publish/bounty math, decline/claim/approve, changes-requested loop,
approval award in metrics, unassign, AI job through real Claude Code with
signed idempotent callback, breaker independence between the two services)
- README/DECISIONS: sudo HOME gotcha, internal URL, non-root performer
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- services/atomizer: standalone Go module implementing §5.1 — Anthropic
OpenAI-compatible chat completions by default, native /v1/messages when
LLM_API_STYLE=anthropic, strict-JSON prompting, defensive fence-stripping
parse with one retry, deterministic equal-split fallback without an API
key, exact coefficient-sum normalization, bearer auth
- services/work-performer: Node 20 http server implementing §5.2 — single
concurrency, /work/{jobId}/TASK.md preparation, attachment downloads,
optional shallow git clone, claude CLI execution with JSON output,
simulated success when the CLI is unavailable (offline demo), artifact
endpoint, idempotent HMAC-signed callbacks with retry, best-effort cancel
- compose profile 'mocks': separate builds/ports/tokens, healthchecks,
${HOME}/.claude(.json) mounted read-only into the performer
- contract tests (go test -tags=contract) for both services; Makefile
test-contract target; verified live incl. a real Claude Code job run
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- aggregations over the immutable bountyAwards ledger: totals, weekly
buckets ($dateTrunc), per-developer and per-customer groupings
- timeline-derived: approval rate, time logged, assigned→approved lead
time, imported→published atomization lead time, open board depth
- developer + consultant dashboards (admin = global consultant view),
date-range filters, CSV export of the ledger
- leaderboard (top 10 by bounty) honoring the new leaderboardOptOut
profile setting
- hand-rolled SVG line and bar charts (~150 lines, no chart library)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- task domain model + exhaustive §4.4 status machine tests (single source of truth)
- per-customer polling workers reconciled every 30s from the customers
collection; panic-safe runs; manual sync-now trigger; status provider
for the admin panel
- §5.3 upsert keyed on (system, key, customerId): refreshes content while
status=imported, records upstream_changed timeline + notification after
- attachments cached into GridFS via connector-authorized downloads
- orphaned tickets flagged with timeline + consultant notification, never
deleted; idempotent across polls
- consultant identity from users.extra.ticketingIdentities per system
- notifications store (insert/list/unread-count/mark-read)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- customer CRUD wizard backend: per-system credential shapes validated via
connector construction, AES-256-GCM at rest, write-only over the API
- ticketing connectors (jira/azure_devops/youtrack/demo) with test-connection
- user management: roles, disable (revokes sessions), force password reset,
delete; self-demotion/disable/delete guards
- admin-editable runtime settings ({_id:app}) incl. atomizer URL override
- audit log written on every privileged mutation + filterable list API
- service status panel: mongo/atomizer/work-performer health + latency with
late-bound breaker, sync and jobs status providers
- tabbed admin UI (customers wizard dialog, users table, settings, status, audit)
- compose: mongo nofile ulimit 64000 (1024 default crashed WiredTiger)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- embedded Go templates + vanilla ES-module JS + hand-written CSS, no build step
- exact §10 beige light / dark design tokens, square edges (radius 2px),
system font stack, visible focus rings
- theme toggle persisted to localStorage and the user profile
- login/register/change-password pages wired to the auth API
- profile page: avatar upload (image-sniffed, old file cleanup), bio,
contacts, arbitrary extra key/value fields, optimistic-concurrency 409
- role-based top navigation with placeholders for later-phase areas
- GET /files/{id} with scope-based access (session) or signed token (§5.1)
- security headers incl. CSP without unsafe-inline scripts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>