Commit Graph

1634 Commits

Author SHA1 Message Date
Maurice 162f2996d2 fix(ci): typed card points, the managed take route, and the failing card tests and ratchets 2026-10-22 16:21:20 +02:00
Maurice db023f4c4d test(assistant): shared card tests, wiki rows and ratchets after the card packages 2026-10-22 15:50:57 +02:00
Maurice 5632916a69 feat(assistant): packing list and to-do cards 2026-10-22 15:50:57 +02:00
Maurice 9895f41096 feat(assistant): journal entry cards, and markdown stripped in shared 2026-10-22 15:50:56 +02:00
Maurice c0f75b9a5e feat(assistant): vacation calendar cards with the days left 2026-10-22 15:50:55 +02:00
Maurice da7af8337d feat(assistant): passport, country and bucket list cards 2026-10-22 15:50:54 +02:00
Maurice fd15a7343e feat(assistant): collection list and saved place cards 2026-10-22 15:50:52 +02:00
Maurice 237e4e4897 feat(assistant): chat, note and poll cards drawn like the Collab tab 2026-10-22 15:50:51 +02:00
Maurice b391ddcc43 feat(assistant): booking and stay cards, and a read of the bookings with their details 2026-10-22 15:50:50 +02:00
Maurice 51e5dbef03 feat(assistant): expense, payment and settle-up cards, and expense links into Costs 2026-10-22 15:50:49 +02:00
Maurice 1e102262b1 feat(assistant): road trip, charging, corridor and transit cards 2026-10-22 15:50:48 +02:00
Maurice 085c5b4263 feat(assistant): hike, walk and route cards with their lines on the map, and "Plan this" 2026-10-22 15:50:47 +02:00
Maurice 5b9b011cdf feat(studio): change a book page by page over MCP, and pick its photos from the gallery 2026-10-22 15:50:44 +02:00
Maurice 0a7452e9cc feat(photos): a photo keeps its quality signals, measured once off the event loop 2026-10-22 15:50:44 +02:00
Maurice 28fcb24435 fix(ci): the book engine's template names count as reached, and formatting 2026-10-22 13:31:00 +02:00
Maurice 44b3f791c8 fix(ci): formatting and two exports nothing imports 2026-10-22 13:17:16 +02:00
Maurice fd7fbef295 fix(ci): message part types across the strict shared build, formatting and trip member write tests 2026-10-22 13:03:59 +02:00
Maurice 76c7323e23 fix(ci): parse errors, two leaky tests and the lint ratchets after the parity round 2026-10-22 12:44:07 +02:00
Maurice b24a82fe33 fix(realtime): journey, atlas, vacay and collection writes in parity 2026-10-22 12:14:28 +02:00
Maurice ce7b5bf453 fix(realtime): trip, member, chat, file, settings, tag and notification writes in parity 2026-10-22 12:14:27 +02:00
Maurice 94b8c3194c fix(realtime): budget, packing and todo writes send what REST sends 2026-10-22 12:14:26 +02:00
Maurice 9c00f96844 fix(realtime): road trip vias and day boundaries send the same events everywhere 2026-10-22 12:14:26 +02:00
Maurice 052964f4ab fix(realtime): booking writes share one use case on REST and MCP 2026-10-22 12:14:25 +02:00
Maurice 262dd97679 fix(realtime): place writes over MCP and plugins send what REST sends 2026-10-22 12:14:25 +02:00
Maurice 072981f837 feat(assistant): a card framework every addon package plugs into 2026-10-22 12:14:24 +02:00
Maurice 621b08d444 feat(tours): a hike's day with sun, weather and warnings, and the proposed line kept for create 2026-10-22 12:14:21 +02:00
Maurice 72ff9600f4 test(realtime): broadcast parity for every MCP write tool
A suite under tests/integration/broadcast-parity boots the app once per
group, runs a write tool through a real MCP session the way the
assistant attaches the registry, runs its REST twin on a twin scene, and
records every broadcast. Per case it checks the exact events in order and
count, that no MCP broadcast skips a socket (the asking tab hears its own
change), that nothing is sent inside a transaction, that every payload
parses with its registered schema, that REST sends the same sequence to
the same room and recipients, and that MCP's keys cover REST's.

A registry test lists the write tools as an MCP client sees them and
fails on a tool without a row, a stale row, or an exemption without a
reason; exemptions run too and must send nothing, and the tools still
waiting for a case are frozen in a list that may only shrink.

The new events the next changes send are registered now (member:updated,
todo:reordered, trips:changed, settings:updated, tags:changed,
notification:read-all, journey:updated, journey:deleted, atlas:changed);
the client keeps them apart as awaiting a sender, and the journey page
already leaves a journey that journey:deleted says is gone.
2026-10-22 00:03:34 +00:00
Maurice fa8a43b16e feat(assistant): expenses, shares, wind, journey tracks and Dawarich checks as MCP tools
- list_budget_items lists a trip's expenses with their ids, payers and
  splits, page by page so no page is cut down on its way to a model;
  get_budget_per_person answers who paid and owes what. Both in a new
  budget-items.mcp.ts, checked like their REST twins.
- get_wind_forecast reads the hourly wind, gusts and direction of a day.
- get_journey_tracks lists a journey's GPX tracks; the line for drawing
  rides under a key the provider never receives.
- The Dawarich wishlist scan and the countries the recordings suggest
  become tools, with their confirming writes, in DawarichAtlasMcp in the
  Atlas group; the shared time window check refuses alike on REST and
  MCP, and the model never sees when the user was last seen in a city.
- The journal's map, tracks and recorded days load with the journey
  group instead of riding in the core of every step.
- The prompt points at list_budget_items for expense ids (the trip
  summary never carried them) and names the shares and the wind tools;
  each new read has its own live step.
2026-10-22 00:03:19 +00:00
Maurice aea37d9914 feat(tours): plan, create and change hikes on the server, for the assistant too
The hiking costing moves to shared, so the planner and the server ask the
router the same way. The road trip router learns to plan a hike on foot
with that costing (Valhalla only: OSRM knows no trail difficulty), to read
heights along a line in chunks and to read the OSM ways a line follows,
all through its one paced queue. A hike router builds on it: the way, its
heights, distance, climb and DIN walking time, and the SAC grades of its
stretches from the trail grade service, each part best effort.

New MCP tools in HikePlanMcp, in the assistant's tours group:
- propose_hike plans a hike without saving it.
- create_hike saves a confirmed hike through the planner's own creation;
  a router that does not answer leaves it pending for the planner, a way
  that cannot be planned is refused and nothing is saved.
- update_tour changes a saved hike against its revision, keeping linked
  stations and refusing what would silently drop drawn legs or stages.
- import_tour_gpx takes a GPX file's text in as tours, like the import.
Same permission checks as REST, broadcasts from the services.

In the assistant a new hike or city walk is an "Add tour" card with its
route and difficulty, undone through delete_place while the tour is
untouched, and a hike being planned shows as a live step.
2026-10-22 00:03:12 +00:00
Maurice 8a8ce4013b fix(assistant): green CI round after the shared ChatGPT plan
- Tests that still knew the ChatGPT sign-in as personal only follow the
  admin's shared plan: the service takes the caller with their role, the
  admin tiles show ChatGPT, the controller tests cover the admin routes.
- The table refused an instance ChatGPT connection with a CHECK, so
  sharing the plan failed. A new migration rebuilds ai_connections
  without that check; the shipped migration stays as it was.
- useChatgptConnect grew past the function size limit: reading the
  clipboard and noticing the return to the tab are helpers of their own.
- The file link factory hands its overrides over apart from the row,
  like every other factory, which ends the deep type instantiation.
- Knip: exports only their own file used are private again, and the
  booking cap reads MAX_WRITES_PER_STEP instead of an alias.
- lint:i18n-keys reaches the tools' own action names through a key
  builder and the connection hints through literal keys.
- MMehrSheet stays in the assistant hints pair only.
2026-10-21 21:40:48 +00:00
Maurice 4abab7a777 feat(assistant): read the conversation from Anthropic's prompt cache
The Anthropic request marked only the instructions and the trip card for
the prompt cache, so every step of a turn paid the whole history again.
It now also marks the end of the history, which the next step starts
from, and the end of what came before the user's question, which every
step of the turn sends unchanged, within the four marks a request takes.

Every provider now reports how much of the input it read from its cache
(Anthropic cache_read_input_tokens, OpenAI cached_tokens), the turn adds
it up, and the usage log line says it, so the saving can be measured.
2026-10-21 21:26:21 +00:00
Maurice f8dc7ad011 fix(assistant): list the admin ChatGPT routes a managed install withholds
The boot check refuses a @ManagedForbidden route the allow list does not
name; the two new admin routes for a shared ChatGPT sign-in were missing.
2026-10-21 23:02:00 +02:00
Maurice 680c52dc85 feat(assistant): an admin can share their ChatGPT plan with everyone
The connection for everyone can now also be the admin's own ChatGPT sign-in.
Whether a plan may be shared that way is the self-hoster's call under their
plan and OpenAI's terms; the form says what it means before the sign-in.
The sign-in starts on the admin route and finishes on the shared one, which
refuses a sign-in for everyone to anyone who is not an admin. The ChatGPT
return reads the clipboard only once the paste handler exists.
2026-10-21 22:57:40 +02:00
Maurice e3d40ddcf6 feat(assistant): the ChatGPT sign-in in a small window, the copied address taken on return
- The sign-in opens in a small window over TREK instead of a new tab.
- Step 2 shows the address the window ends on, so the error page there is
  expected rather than alarming.
- Back in TREK the copied address is read off the clipboard where the browser
  allows it and the sign-in finishes; else the field has the cursor.
- The token and OAuth client factories hand their columns over apart from
  the row, as the others do (TS2589).
2026-10-21 22:50:41 +02:00
Maurice 00b50e280f revert(assistant): drop the ChatGPT relay, open-source apps keep the loopback sign-in
OpenAI offers a fixed web redirect for Sign in with ChatGPT only to selected
commercial partners; open-source apps sign in through the 127.0.0.1 loopback
callback. The relay could never be switched on, so it goes again.
2026-10-21 22:49:01 +02:00
Maurice f8e29dd218 feat(assistant): Sign in with ChatGPT can come back to TREK by itself
Once the TREK project has a client id registered with OpenAI, the sign-in
goes out with the relay page as its redirect address and the install's own
settings in its state; the relay sends the browser back there and the
settings finish the sign-in, nothing to paste. The relay sees the code but
cannot redeem it without the install's PKCE verifier. Without the project's
client id, or for an install without an https address, the loopback page
and the pasted address stay as they are.

relay/chatgpt-callback/index.html is the page to publish.
2026-10-21 22:43:44 +02:00
Maurice 2fbff51299 feat(assistant): change cards in the style of the planner's day list
A waiting change is one row as in the day list: a round choice in front,
what it touches in bold, a faint line with what happens and when. No switch,
nothing to fold open, no day band: the planner's day list already shows the
suggestion among the day's stops. Whether the days still fit is one pill in
the card's head, with what to look at on hover.

Also mends the comment the rebase onto dev split in json-columns.ts.
2026-10-21 22:39:43 +02:00
Maurice 55c6bad295 fix(assistant): readable cards for any tool, and the CI round
- A card for a tool without one of its own names what it works on: the place
  of an assignment, the day, the note, the booking; its arguments sit under
  the labels the other cards use, a new order reads as the names in order.
  28 frequent tools carry their own action name in every language.
- The server's own steps without a card still refuse, as before.
- Tests: the rate limit is asked one request after another, the mention list
  closes on the caret move a browser reports, the place factory hands its
  category over as a plain id, eleven files formatted.
2026-10-21 22:29:59 +02:00
Maurice e5f1f573c5 feat(assistant): every MCP tool of TREK, the core first and the addons on request
The assistant offered 25 hand-picked tools. It now offers every tool the MCP
registry holds, but a short denylist with a reason per tool (deleting the
trip, share, invite and feed links, membership changes, fetching an address
the model picks, documents to the provider, instance-wide categories and
holidays). The scopes widen to every addon but trips:delete, the share
scopes, file contents and plugins.

- A tool annotated read-only runs at once, every other one waits as a change
  card; reads that fetch a planted address wait too.
- A turn starts with the trip's core tools; use_addon_tools loads tours, road
  trip, journey, vacay, atlas, collections, trip chat, files, account or
  plugin tools for the rest of the turn.
- A writing tool without a card of its own gets one from its arguments:
  add, change or remove, the part of TREK it works in, the trip's days,
  places and people named.
- The boot check fails on a tool that shares, invites or publishes and is
  neither denied nor known to only take back.
2026-10-21 22:29:59 +02:00
Maurice b721234249 chore(assistant): mark the step store and the model pick as independent writes
lint:tx counted the three step writes of the store and the ChatGPT sign-in
renewal before a model pick as one sequence. Each stands on its own.
2026-10-21 22:29:58 +02:00
Maurice a1f97ba548 style: format two ai-connections files 2026-10-21 22:29:58 +02:00
Maurice 77ad0a06d0 test: factories hand their overrides over apart from the row
The assistant tables gave Users three more relations, and a spread of
overrides checked against RequiredEntityData now ran tsc past its
instantiation depth (TS2589). Every factory passes its overrides as
createRow's own argument, the way rows.ts documents it.
2026-10-21 22:29:58 +02:00
Maurice 3c3a228737 fix(assistant): lint, types and tests for the CI round
- agent loop and decisions without await in loops: steps as recursion,
  calls and applied changes in order through one promise chain, the
  independent reads and claims in parallel; part mapping in its own helpers
- place card, header and weather strip without refs or components created
  in render; long hooks and components split; state reset during render
- trip notes only in a turn's tool session, never an undo's; map view
  reported only while the assistant can run
- place strip scrolls through the strip's own smooth scroll, no physical side
- tests follow the raised limits and the new card fields; toasts read through
  a mocked useToast instead of a window global; baselines lowered where the
  counts fell
2026-10-21 22:29:58 +02:00
Maurice b6f7488591 fix(assistant): green CI round, trip notes the assistant can keep, calmer change cards
- the assistant keeps facts for a trip (remember_for_trip) as a change card,
  applied into the user's trip notes; existing expenses can be changed
- change card fields as a few icon chips with the rest folded under Details,
  the day band marks only what changes, the week grid as compact tiles
- no map button on receipts of things that have no place on the map
- tests follow the composer's accessible name, the receipt's status icon and
  the GL map's container; the hanging stream helper honours an early abort
- Postgres probe: qualified columns in the upsert updates; entities restored
  to the generator's output; strict ratchet reads the SDK client as untyped
2026-10-21 22:29:57 +02:00
Maurice 26df56d76c feat(assistant): one AI tile for assistant, parsing and MCP, a planner-aware chat
The three AI addons share one tile in the integration column; a dialog holds
the connection, the assistant's limits and AI parsing, which now reads with
the assistant's connection unless an install keeps its own. Existing parsing
configs stay where they are and keep winning.

The chat sees the map on screen, offers next questions under an answer,
shows its live step in the window head, previews waiting changes inside the
day list, checks whether a day still works, folds a multi-day plan into a
week grid, keeps per-trip notes and can estimate costs. An empty or cut-off
answer gets one push instead of ending silently, and the assistant's own
step and size limits are raised.
2026-10-21 22:29:57 +02:00
Maurice 214984f398 feat(assistant): trip assistant chat with your own AI connection
Adds an in-app assistant that reads and plans the open trip. Users connect
their own provider (Sign in with ChatGPT, or an Anthropic, OpenAI, Gemini or
OpenRouter key) or use the one the admin set up, including a custom
OpenAI-compatible server. It is an addon and only shows while a connection
is usable.

The chat runs on the existing MCP tools, pinned to the trip. Every change is
held as a change card the user applies or discards, and applied changes can
be undone. On the desktop it is a floating window that can be moved and
resized; on the phone it is fullscreen. Search results show as place cards
that can go onto a day, weather lookups as a strip, proposed places as
ghost markers on the map with a before/after switch, and an answer can be
shared into the trip chat. Booking files can be dropped in and are read
into change cards.
2026-10-21 22:29:56 +02:00
Maurice 3101b36f3d fix(journey,tours): read a day's stays as a read, give the services the request context in the e2e runs and hold the tests to the foot-only walks and the translated notices 2026-10-21 21:16:36 +02:00
Maurice 5dc945145f fix(journey): keep the journey page and maps within their lint gates, format the journey locales 2026-10-21 20:00:07 +02:00
Maurice d62fc284e1 fix(journey): share the stays of a day report only with the recorded days, and hold the share read tests to the two new flags 2026-10-21 19:08:25 +02:00
Maurice 8f53d98d45 feat(journey): show the plan, what was recorded, the entries and the photos as layers of the journey map
Every journey map (the desktop aside, the phone screens and the shared page)
now carries four switches: Plan, Recorded, Entries and Photos, each with its
count, a spinner while it loads, the warning tone when it could not be read
and the reason when it has nothing to show. A switch only hides, in place:
the map is not rebuilt and keeps its view, and the choice is kept in this
browser per journey (per link on a shared page, by a hash of its token).

The plan draws the places the linked trips put on their days as hollow dashed
pins and the trips' GPX routes dashed; a place an entry was written about is
not drawn twice, the entry's pin carries a check instead. The stays a day
report was taken over from show as dots in the colour of their day. Marks on
one spot join into a disc with their number and open as a list; a picked
place or stay opens a card with its trip, days and times and leads to its
entry. A key beside the switches explains every pin and line and says that
a plan is no proof of a visit. The phone timelines now show the photos too.

The GPX routes come with the map's layers through the linked trips, read
only while the journey's track switch is on; the frozen /tracks answer stays
Studio's. The share settings on desktop and phone get Trip plan and Recorded
routes under Map, off by default and only switchable while the map is shared.
2026-10-21 18:55:54 +02:00