mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
fix(ci): card points re-typed for the non-strict builds, formatting, strict ratchet and two assistant e2e checks
This commit is contained in:
@@ -16,7 +16,11 @@ const SHOWN = 8;
|
||||
|
||||
function listCard(input: AnswerInput, rows: Row[], toRow: (raw: Row) => BookingRow): TrekCard | null {
|
||||
const scope = scopeOfCard(input.card);
|
||||
return bookingCard('none', rows.slice(0, SHOWN).map((raw) => bookingItemOf(toRow(raw), scope)), rows.length);
|
||||
return bookingCard(
|
||||
'none',
|
||||
rows.slice(0, SHOWN).map((raw) => bookingItemOf(toRow(raw), scope)),
|
||||
rows.length,
|
||||
);
|
||||
}
|
||||
|
||||
/** A stay listed once: the list joins each booking that links it, so one stay can come twice. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IMPORT_BOOKING_TOOL } from '../../assistant-tools.constants';
|
||||
import type { TripCard } from '../../assistant-context';
|
||||
import { IMPORT_BOOKING_TOOL } from '../../assistant-tools.constants';
|
||||
import type { DomainCards, PreviewContext, ToolArgs } from '../card-types';
|
||||
import { argId, clipped, idIn } from '../card-values';
|
||||
import { BOOKING_ANSWERS } from './booking-answer';
|
||||
|
||||
@@ -28,7 +28,10 @@ function expenseName(ctx: PreviewContext, args: ToolArgs): string {
|
||||
|
||||
/** Who shares a stored expense, by name. */
|
||||
function sharedBy(ctx: PreviewContext, row: Row | undefined): string {
|
||||
return memberNames(ctx, rowsOf(row?.members).map((member) => member.user_id));
|
||||
return memberNames(
|
||||
ctx,
|
||||
rowsOf(row?.members).map((member) => member.user_id),
|
||||
);
|
||||
}
|
||||
|
||||
/** "Ana → Ben", from the two people of a payment. */
|
||||
|
||||
@@ -117,7 +117,11 @@ export function splitOf(
|
||||
max: number,
|
||||
): Pick<CardExpense, 'split' | 'shares' | 'moreShares'> {
|
||||
if (members.length === 0) return { split: 'none', shares: [], moreShares: 0 };
|
||||
const equal = splitEqualShares(toMinor(total), members.map((member) => ({ user_id: member.id })), itemId);
|
||||
const equal = splitEqualShares(
|
||||
toMinor(total),
|
||||
members.map((member) => ({ user_id: member.id })),
|
||||
itemId,
|
||||
);
|
||||
const shares = members.map((member) => ({
|
||||
person: personFrom(card, member.id, member.name, member.avatarUrl),
|
||||
amount: member.amount ?? (equal[member.id] ?? 0) / 100,
|
||||
|
||||
@@ -73,12 +73,15 @@ export const COLLECTION_CARDS: DomainCards = {
|
||||
list_collections: { answer: listsAnswer },
|
||||
find_place_in_collections: { answer: membershipAnswer },
|
||||
...WRITE_CARDS,
|
||||
create_collection: { ...WRITE_CARDS.create_collection, undo: DELETE_CREATED_LIST },
|
||||
create_collection: { ...writeCards('create_collection', WRITES.create_collection), undo: DELETE_CREATED_LIST },
|
||||
save_place_to_collection: {
|
||||
...WRITE_CARDS.save_place_to_collection,
|
||||
...writeCards('save_place_to_collection', WRITES.save_place_to_collection),
|
||||
undo: DELETE_SAVED_PLACE,
|
||||
argPolicy: NO_IMAGE,
|
||||
},
|
||||
update_collection_place: { ...WRITE_CARDS.update_collection_place, argPolicy: NO_IMAGE },
|
||||
update_collection_place: {
|
||||
...writeCards('update_collection_place', WRITES.update_collection_place),
|
||||
argPolicy: NO_IMAGE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,12 +24,7 @@ import {
|
||||
type ListItem,
|
||||
type PackingTier,
|
||||
} from './packing-rows';
|
||||
import {
|
||||
resolvePackedState,
|
||||
type PackingCardBag,
|
||||
type PackingCardItem,
|
||||
type PackingListCard,
|
||||
} from '@trek/shared';
|
||||
import { resolvePackedState, type PackingCardBag, type PackingCardItem, type PackingListCard } from '@trek/shared';
|
||||
|
||||
/**
|
||||
* The card each packing change shows inside its change card, from the call's
|
||||
@@ -330,37 +325,56 @@ export function packingAssigneesCard(ctx: PreviewContext, args: ToolArgs, loaded
|
||||
const before = rowsOf(recordOf(recordOf(loaded).assignees)[raw]).flatMap((row) => positiveId(row.user_id) ?? []);
|
||||
const inside = tripPacking(ctx.card).filter((item) => !item.placeholder && item.category === raw);
|
||||
const personal = inside.length > 0 && inside.every((item) => item.isPrivate);
|
||||
return packingCard({ type: 'trip' }, 'category', [], [
|
||||
{
|
||||
key: { by: 'category', name, slot: slotOf(ctx.card, raw, personal) },
|
||||
assignees: peopleOf(ctx.card, chosen, 6),
|
||||
assigneesRemoved: peopleOf(ctx.card, before.filter((id) => !chosen.includes(id)), 6),
|
||||
items: [],
|
||||
count: inside.length,
|
||||
packed: inside.filter((item) => item.checked).length,
|
||||
},
|
||||
]);
|
||||
return packingCard(
|
||||
{ type: 'trip' },
|
||||
'category',
|
||||
[],
|
||||
[
|
||||
{
|
||||
key: { by: 'category', name, slot: slotOf(ctx.card, raw, personal) },
|
||||
assignees: peopleOf(ctx.card, chosen, 6),
|
||||
assigneesRemoved: peopleOf(
|
||||
ctx.card,
|
||||
before.filter((id) => !chosen.includes(id)),
|
||||
6,
|
||||
),
|
||||
items: [],
|
||||
count: inside.length,
|
||||
packed: inside.filter((item) => item.checked).length,
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/** A bag head on a card of its own: what a change to one bag shows. */
|
||||
function bagCard(card: TripCard, bag: PackingCardBag): PackingListCard {
|
||||
const inside = tripPacking(card).filter((item) => !item.placeholder && bag.id !== null && item.bagId === bag.id);
|
||||
return packingCard({ type: 'trip' }, 'bag', [bag], [
|
||||
{
|
||||
key: { by: 'bag', bagKey: bag.key },
|
||||
assignees: [],
|
||||
assigneesRemoved: [],
|
||||
items: [],
|
||||
count: inside.length,
|
||||
packed: inside.filter((item) => item.checked).length,
|
||||
},
|
||||
]);
|
||||
return packingCard(
|
||||
{ type: 'trip' },
|
||||
'bag',
|
||||
[bag],
|
||||
[
|
||||
{
|
||||
key: { by: 'bag', bagKey: bag.key },
|
||||
assignees: [],
|
||||
assigneesRemoved: [],
|
||||
items: [],
|
||||
count: inside.length,
|
||||
packed: inside.filter((item) => item.checked).length,
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/** The bag a call names (`bagId`), as the lookup read it. */
|
||||
function namedBag(card: TripCard, args: ToolArgs, loaded: unknown): PackingCardBag | null {
|
||||
const bagId = argId(args, 'bagId');
|
||||
return bagId === null ? null : bagOf(card, rawBags(loaded).find((bag) => bag.id === bagId));
|
||||
return bagId === null
|
||||
? null
|
||||
: bagOf(
|
||||
card,
|
||||
rawBags(loaded).find((bag) => bag.id === bagId),
|
||||
);
|
||||
}
|
||||
|
||||
/** `create_packing_bag`: the new bag's head, in its colour (indigo without one) and with its limit. */
|
||||
|
||||
@@ -204,7 +204,11 @@ export function slotOf(card: TripCard | null, category: string | null, personal:
|
||||
|
||||
/** The people of an assignee list (`[{ user_id }]`), as trip members. */
|
||||
export function assigneesOf(card: TripCard, raw: unknown): CardPerson[] {
|
||||
return peopleOf(card, rowsOf(raw).flatMap((row) => positiveId(row.user_id) ?? []), 6);
|
||||
return peopleOf(
|
||||
card,
|
||||
rowsOf(raw).flatMap((row) => positiveId(row.user_id) ?? []),
|
||||
6,
|
||||
);
|
||||
}
|
||||
|
||||
/** One bag as `list_packing_bags` answers it. */
|
||||
@@ -302,7 +306,11 @@ export function packingGroups(
|
||||
items: readonly ListItem[],
|
||||
options: GroupOptions,
|
||||
): { groups: PackingCardGroup[]; moreGroups: number } {
|
||||
const buckets = bucketsOf(card, items.filter((item) => !item.placeholder), options);
|
||||
const buckets = bucketsOf(
|
||||
card,
|
||||
items.filter((item) => !item.placeholder),
|
||||
options,
|
||||
);
|
||||
let left = options.maxRows ?? MAX_PACKING_ROWS;
|
||||
const perGroup = options.fillSingleGroup && buckets.length === 1 ? left : ROWS_PER_GROUP;
|
||||
const groups = buckets.slice(0, MAX_CARD_GROUPS).map((bucket): PackingCardGroup => {
|
||||
|
||||
@@ -170,7 +170,11 @@ function todoAssigneesCard(ctx: PreviewContext, args: ToolArgs, loaded: TodoAssi
|
||||
category,
|
||||
slot: todoSlot(ctx.card, args.categoryName),
|
||||
assignees: peopleOf(ctx.card, chosen, 6),
|
||||
assigneesRemoved: peopleOf(ctx.card, before.filter((id) => !chosen.includes(id)), 6),
|
||||
assigneesRemoved: peopleOf(
|
||||
ctx.card,
|
||||
before.filter((id) => !chosen.includes(id)),
|
||||
6,
|
||||
),
|
||||
items: [],
|
||||
count: inList.length,
|
||||
open: inList.filter((todo) => !todo.checked).length,
|
||||
|
||||
@@ -113,7 +113,7 @@ export function describeSettings(ctx: PreviewContext, args: Args, loaded: SavedS
|
||||
after: settingText(change.after),
|
||||
});
|
||||
}
|
||||
return { subject: clip(ctx.card.title), rows, dayId: null, placeIds: [] };
|
||||
return { subject: clip(ctx.card.title), rows, dayId: null, placeIds: [], tool: 'update_roadtrip_settings' };
|
||||
}
|
||||
|
||||
export function describeDayEnd(ctx: PreviewContext, args: Args): Described {
|
||||
@@ -129,7 +129,9 @@ export function describeImportRoute(ctx: PreviewContext, args: Args): Described
|
||||
const names = Array.isArray(args.stops)
|
||||
? args.stops.map((stop: unknown) => text(recordOf(stop).name)).filter((name) => name !== '')
|
||||
: [];
|
||||
const rows = dayRows(ctx, dayId).add('quantity', String(names.length)).add('route', clip(routeText(names)));
|
||||
const rows = dayRows(ctx, dayId)
|
||||
.add('quantity', String(names.length))
|
||||
.add('route', clip(routeText(names)));
|
||||
const ends = names.length > 0 ? routeText([names[0] ?? '', names[names.length - 1] ?? '']) : '';
|
||||
return { subject: ends, rows, dayId, placeIds: [] };
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { CardReader, PreviewContext, ToolArgs } from '../card-types';
|
||||
import { canonicalJson, clipped, finite, recordOf, type Row } from '../card-values';
|
||||
import { hikeCard } from './tour-route.cards';
|
||||
import {
|
||||
argText,
|
||||
climbOf,
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
straightMetres,
|
||||
whole,
|
||||
} from './tour-card-values';
|
||||
import { hikeCard } from './tour-route.cards';
|
||||
import {
|
||||
hikingPreferencesOf,
|
||||
TOUR_ROUTE_LIMITS,
|
||||
|
||||
@@ -104,7 +104,11 @@ export const VACAY_ANSWER_CARDS = {
|
||||
const stats = statsOf(input.value);
|
||||
if (!stats || stats.length === 0) return null;
|
||||
const viewerId = input.card.viewerId;
|
||||
const people = peopleOf(stats.map((row) => row.personId), knownPeople(null, [], stats), viewerId);
|
||||
const people = peopleOf(
|
||||
stats.map((row) => row.personId),
|
||||
knownPeople(null, [], stats),
|
||||
viewerId,
|
||||
);
|
||||
const order = new Map(people.map((person, index) => [person.id, index]));
|
||||
const balances = keepKnown(stats, people)
|
||||
.sort((a, b) => (order.get(a.personId) ?? 0) - (order.get(b.personId) ?? 0))
|
||||
|
||||
@@ -96,7 +96,10 @@ function toggleProposal(viewerId: number, args: ToolArgs, loaded: VacayLoaded, d
|
||||
const was = existing ? counted(existing.kind, existing.fraction) : 0;
|
||||
const will = outcome === 'remove' ? 0 : outcome === 'blocked' ? was : counted(kind, fraction);
|
||||
const year = Number(date.slice(0, 4));
|
||||
const periodYear = periodOf(date, loaded.stats.find((row) => row.personId === personId && row.year === year));
|
||||
const periodYear = periodOf(
|
||||
date,
|
||||
loaded.stats.find((row) => row.personId === personId && row.year === year),
|
||||
);
|
||||
const counts = kind === 'vacation' && (outcome === 'add' || outcome === 'convert');
|
||||
return {
|
||||
date,
|
||||
|
||||
@@ -51,7 +51,9 @@ function tripDatesOf(card: TripCard): string[] {
|
||||
|
||||
/** The dated days of the trip inside `months`, as many as a card holds. */
|
||||
export function tripDatesIn(card: TripCard, months: readonly CardMonth[]): string[] {
|
||||
return tripDatesOf(card).filter((date) => inMonths(date, months)).slice(0, VACAY_CARD_MAX_DATES);
|
||||
return tripDatesOf(card)
|
||||
.filter((date) => inMonths(date, months))
|
||||
.slice(0, VACAY_CARD_MAX_DATES);
|
||||
}
|
||||
|
||||
/** The company holidays inside `months`, each date once. */
|
||||
|
||||
@@ -130,7 +130,10 @@ export class RoadtripPlanningMcp {
|
||||
});
|
||||
const betweenStops = (alongKm: number): [string, string] | null => {
|
||||
if (anchors.length < 2) return null;
|
||||
const index = insertIndexForAlong(anchors.map((anchor) => anchor.alongKm), alongKm);
|
||||
const index = insertIndexForAlong(
|
||||
anchors.map((anchor) => anchor.alongKm),
|
||||
alongKm,
|
||||
);
|
||||
return [anchors[index - 1].name, anchors[index].name];
|
||||
};
|
||||
const hits = new Map<
|
||||
|
||||
Reference in New Issue
Block a user