Бесплатный интерактивный курс · aicoding.space
trip-planner: поездка → мобильный сайт-маршрут
Курс по пакету @dzhechkov/trip-planner для участников harness-мастерской. За двенадцать разделов ты пройдёшь путь Миры: от вороха вкладок про Казань до одного самодостаточного HTML-файла с днями, картами, погодой и проверенными контактами — и разберёшься, какие правила честности стоят за этим файлом.
Содержание курса
1. Зачем нужен trip-planner
Какую проблему решает пакет и что он выдаёт вместо списка ссылок
Ключевая мысль: мобильный сайт-маршрут
Знакомься: Мира — участница harness-мастерской. В прошлых курсах она осваивала команду dz и конвейер разработки функций, а сегодня у неё задача из обычной жизни: через две недели поездка в Казань на три дня.
План пока выглядит так: одиннадцать открытых вкладок, три голосовых сообщения от друзей и заметка «музей? уточнить часы». Информации не мало — её слишком много, и в дороге, одной рукой, с рюкзаком на плече, ею не воспользуешься.
Пакет @dzhechkov/trip-planner решает именно эту задачу. Ты описываешь поездку словами — город, даты, время приезда и отъезда, адрес жилья, состав компании, ограничения, — а получаешь мобильный сайт-маршрут: один HTML-файл, который открывается на телефоне и работает без интернета.
Разберём название по частям:
- мобильный — одна колонка, крупные кнопки, навигация по дням не уезжает при прокрутке; до всего можно дотянуться большим пальцем;
- сайт — не текстовый список, а страница с раскрывающимися карточками, ссылками на карты и блоком погоды;
- маршрут — точки расставлены по дням в порядке, который не гоняет тебя через весь город дважды.
Исходники и публичное зеркало: github.com/djd1m/dz-harness.
Компромиссы. Сильная сторона: результат работает офлайн и не зависит от чужого сервиса — сеть в поездке пропадает чаще, чем хочется. Слабая: пакет рассчитан на конкретную поездку с датами, для мечтательного «куда бы съездить летом» он избыточен.
💬 Просто попроси.
- «Что умеет trip-planner?» → ассистент откроет README пакета и перескажет, что получается на выходе.
- «Хочу мобильный сайт-маршрут по Казани на три дня» → ассистент запустит навык trip-planner и начнёт с уточняющих вопросов о поездке.
2. Установка: npx, предпросмотр и поддержка других ассистентов
Как поставить набор в проект и как заглянуть внутрь, ничего не записав
Ключевая мысль: установка пакета
Мира открывает пустую папку проекта и хочет действовать осторожно: сначала посмотреть, что появится на диске, и только потом что-то записывать.
Установка идёт через npx — глобально ставить ничего не нужно. Одна команда копирует набор в каталог .claude/ текущего проекта:
npx @dzhechkov/trip-planner init— установка набора: четыре навыка, команда/trip-planner, правило и контекстный фрагмент;npx @dzhechkov/trip-planner init --dry-run— предпросмотр: печатает, что было бы скопировано, и не пишет ни байта;npx @dzhechkov/trip-planner init --force— перезапись, если набор в этой папке уже стоит.
Есть второй путь — через общий установщик @dzhechkov/harness-cli: npm install -g @dzhechkov/harness-cli, затем dz install @dzhechkov/trip-planner --target hermes. Он нужен, когда ты работаешь не в Claude Code, а в другом ассистенте: тот же канонический SKILL.md проецируется в его каталог, например .hermes/skills/trip-planner/.
После установки в Claude Code достаточно написать /trip-planner Казань 3 дня, 10–12 июля, приезд 10:30 поезд, отъезд 21:00 самолёт, жильё ул. Баумана 1, 2 чел (с ребёнком 5 лет), без алкоголя, вегетарианцы, бюджет 4000₽/день — или просто описать поездку словами: навык подхватится сам.
Страница пакета: npmjs.com/package/@dzhechkov/trip-planner, зеркало исходников: github.com/djd1m/dz-harness.
Компромиссы. Сильная сторона: копирование в проект делает набор видимым и правимым — файлы лежат рядом, их можно прочитать. Слабая: копия не обновляется сама — свежая версия появляется только после повторного запуска с --force.
💬 Просто попроси.
- «Поставь trip-planner в этот проект» → ассистент выполнит npx @dzhechkov/trip-planner init и покажет список скопированных файлов.
- «Сначала покажи, что установится» → ассистент прогонит init --dry-run и напечатает план без записи на диск.
3. Команды набора: init, list, doctor
Четыре команды установщика и то, в какой момент каждая из них выручает
Ключевая мысль: команды init, list и doctor
У установщика ровно три рабочих команды, и Мира выучивает их за минуту, потому что каждая отвечает на один вопрос.
init— «поставь». Команда по умолчанию: запуск без аргументов означает именно её. Копирует навыки, команду/trip-planner, правило и фрагмент контекста в.claude/, а рядом кладёт манифест.trip-planner.json— список всего, что было записано.list— «что внутри». Печатает навыки, которые входят в набор, ничего не устанавливая; удобно заглянуть, прежде чем решишь ставить.doctor— «цело ли». Читает манифест и проверяет, что каждый записанный файл на месте. Если файла нет — значит, его удалили или перезаписали; лечитсяinit --force.
К ним два модификатора: --dry-run (предпросмотр без записи) и --force (разрешить перезапись). Незнакомый флаг установщик не проглатывает молча: опечатка вроде --froce останавливает запуск с ошибкой, а не тихо превращается в установку без перезаписи.
Почему это важно. Тихая подмена — худший вид ошибки: ты уверен, что запустил перезапись, а на диске остались старые файлы. Громкий отказ дешевле разбирательства через неделю.
Компромиссы. Сильная сторона: три команды, каждая с одной обязанностью, и явный манифест как источник правды. Слабая: doctor сверяет наличие файлов, а не их содержимое — руками изменённый навык он считает целым.
💬 Просто попроси.
- «Проверь, цел ли установленный trip-planner» → ассистент выполнит doctor и покажет пропавшие файлы, если они есть.
- «Какие навыки входят в набор?» → ассистент выполнит list и перечислит их.
4. Что именно получается на выходе
Один файл и восемь обязательных свойств сайта
Ключевая мысль: самодостаточный HTML-файл
Результат работы — самодостаточный HTML-файл по пути trip/<город>/index.html. Самодостаточный значит буквально: стили и скрипты лежат внутри самого файла, сборки нет, внешних библиотек нет.
Вот как он устроен, если нарисовать схему словами:
index.html
├── закреплённая навигация ← День 1 · День 2 · День 3
├── День 1
│ ├── погода + совет по одежде ← считается прямо на странице
│ ├── ссылка «маршрут дня» ← все точки дня одной ссылкой
│ └── карточки точек ← нажми → время, цена, советы
│ └── у заведения: адрес, телефон/сайт, отзывы, дата проверки
└── День 2, День 3 …Мира открывает такой файл в поезде и первым делом нажимает на карточку — та раскрывается и показывает время, цену и пару советов. Восемь свойств, которые обязаны быть в готовом файле: мобильная вёрстка под одну руку, без горизонтальной прокрутки; лента дня с раскрывающимися карточками; метка на Яндекс.Картах для каждой точки; ссылка на маршрут для каждого дня; проверенные контакты и ссылка на отзывы с датой проверки для каждого названного заведения; кнопка «Купить билет» там, где нужна предварительная бронь; блок погоды с советом по одежде; рестораны, отобранные под твои ограничения.
Единственный запрос в сеть у готовой страницы — прогноз погоды. Пропал интернет — страница остаётся рабочей, исчезает только прогноз.
Компромиссы. Сильная сторона: файл можно отправить попутчику в мессенджер, и тот откроет его, ничего не устанавливая. Слабая: самодостаточный файл — это снимок на момент сборки; если завтра музей поменяет часы работы, сами по себе они в нём не обновятся.
💬 Просто попроси.
- «Покажи, что будет в готовом файле» → ассистент перечислит восемь обязательных свойств сайта.
- «Отправь маршрут попутчику» → ассистент напомнит, что это один самодостаточный файл, и его достаточно переслать как вложение.
5. Бриф поездки: о чём тебя спросят и почему
Семь обязательных полей и что ломается, когда одного не хватает
Ключевая мысль: бриф поездки
Первый шаг конвейера — сбор брифа. Мира пишет «Казань, три дня» и ждёт готового плана, но получает встречные вопросы. Это не бюрократия: каждое поле брифа что-то определяет в итоговом файле.
Семь обязательных полей:
1. город и число дней — сколько будет вкладок с днями;
2. даты — по ним запрашивается прогноз погоды;
3. прибытие — время и способ; первый день начинается после реального приезда, а не в девять утра;
4. отъезд — последний день заканчивается до выезда, с запасом на дорогу;
5. адрес жилья — точка старта и финиша каждого дня, к ней привязывается маршрут;
6. количество человек — влияет на бюджет и выбор заведений;
7. ограничения — алкоголь, вегетарианство, дети, бюджет в день, подвижность.
Правило простое: чего не хватает — то спрашивают, а не додумывают. Навык останавливается и задаёт вопрос, потому что придуманное время приезда сдвигает весь первый день, и ошибку замечаешь уже на вокзале.
Компромиссы. Сильная сторона: бриф ловит противоречия заранее — «приезд в 22:40» и «экскурсия в первый день» не уживаются, и это видно до сборки. Слабая: одним сообщением не обойтись — на вопросы придётся ответить, и результат появится не сразу.
💬 Просто попроси.
- «Составь бриф поездки по моему сообщению и скажи, чего не хватает» → ассистент разложит текст по семи полям и назовёт пробелы.
- «Приезд в 22:40, что это меняет?» → ассистент объяснит, что первый день сжимается до ужина рядом с жильём.
6. Конвейер из пяти шагов
Сбор брифа → исследование → маршрут → сайт → валидация
Ключевая мысль: конвейер из пяти шагов
Между «Казань, три дня» и готовым файлом лежит конвейер из пяти шагов, и порядок в нём не случайный: каждый шаг работает на том, что произвёл предыдущий.
- Сбор брифа (навык
explore) — семь обязательных полей и явные ограничения. - Исследование (навык
goap-research-ed25519) — точки и заведения с координатами, часами работы, контактами, ссылками на отзывы и пометкой о предварительной брони; ограничения уже здесь работают как фильтр. - Маршрут — раскладка точек по дням с учётом времени приезда и отъезда, порядок внутри дня подбирается так, чтобы не возвращаться по своим следам.
- Сайт (навык
frontend-design) — шаблон страницы заполняется данными маршрута. - Валидация — чек-лист: нет ли точки без координат, заведения без контактов, дня без маршрута и погоды.
Почему порядок жёсткий. Нельзя раскладывать точки по дням, пока неизвестны их координаты, и нельзя рисовать страницу, пока нет дней. Пропустить шаг — не ускорить работу, а перенести ошибку на более дорогой этап; Мира это уже проходила на конвейере разработки функций.
Компромиссы. Сильная сторона: у каждого шага свой проверяемый результат, поэтому видно, где именно всё пошло не так. Слабая: шагов пять, и полный проход по большому городу занимает заметное время.
💬 Просто попроси.
- «Объясни, на каком шаге конвейера мы сейчас» → ассистент назовёт текущий шаг и его результат.
- «Пересобери только сайт, исследование не трогай» → ассистент повторит шаг сборки страницы на уже собранных данных.
7. Ограничения — жёсткие фильтры, а не пожелания
Почему «без алкоголя» отсекает варианты, а не превращается в сноску
Ключевая мысль: жёсткие фильтры
Ограничения Миры — «без алкоголя, вегетарианцы, с ребёнком пяти лет, бюджет 4000 ₽ в день» — в этом пакете работают как жёсткие фильтры.
Жёсткие фильтры означают: кандидат, нарушающий условие, не попадает в план вовсе. Не попадает с пометкой, не попадает со сноской «уточните на месте» — просто заменяется другим. Разница видна на примере: ресторан с одним мясным меню при мягком подходе оказался бы в списке с примечанием, и Мира с ребёнком пришла бы туда голодной.
Что именно фильтруется:
- алкоголь — заведения, где смысл в барной карте, отсекаются;
- вегетарианство — нужно реальное вегетарианское меню, а не «есть салат»;
- дети — оценивается пригодность места для пятилетнего;
- бюджет — суммарная стоимость дня укладывается в заявленную сумму;
- подвижность — маршрут не строится через лестницы, если это заявлено.
Правило одной фразой: нарушил условие — заменяется, а не помечается. Пометка перекладывает проверку обратно на путешественника, ровно в тот момент, когда проверять уже поздно.
Компромиссы. Сильная сторона: план исполним без ручной перепроверки каждой строки. Слабая: строгие фильтры сужают выбор, и в маленьком городе подходящих заведений может остаться совсем немного — тогда честнее сказать об этом, чем ослабить условие втихую.
💬 Просто попроси.
- «Добавь ограничение: без лестниц, едем с коляской» → ассистент внесёт его в бриф и перестроит маршрут.
- «Почему в плане нет этого ресторана?» → ассистент назовёт нарушенное ограничение, из-за которого он отсеян.
8. Проверенные контакты и запрет на выдуманные данные
Правило доказательства: адрес, связь, отзыв с датой — или замена
Ключевая мысль: проверенные контакты
Самая опасная ошибка планировщика — правдоподобная выдумка. Координаты «примерно там», телефон «наверное такой», рейтинг «где-то 4,6» выглядят как данные и ведут себя как данные, пока Мира не приедет по этому адресу и не обнаружит там шиномонтаж.
Поэтому в пакете действует правило доказательства: названное заведение не попадает в файл, пока у него нет трёх подтверждений — проверенного адреса, официального сайта или телефона и отдельной ссылки на отзывы с датой проверки. Нет доказательства — заведение заменяется другим или маршрут не проходит валидацию.
Что ещё запрещено:
- выдумывать координаты — неизвестная точка помечается «координаты уточняются», а не заполняется правдоподобным числом;
- переносить рейтинг без источника — цифра без ссылки и даты просто не показывается; она необязательная и никогда не выводится по догадке;
- придумывать цены и часы работы — то же правило, тот же исход.
Отдельная ссылка на отзывы — не формальность. Официальный сайт заведения рассказывает о себе сам; независимый отзыв — это второй, несогласованный источник. Дата проверки нужна, чтобы через полгода было видно, насколько сведения свежие, а не только то, что они есть.
Компромиссы. Сильная сторона: контакты в файле можно набирать не глядя, каждое заведение подтверждено двумя источниками. Слабая: требование доказательства отсеивает интересные, но слабо представленные в сети места — маленькая семейная пекарня без сайта может не пройти этот отбор.
💬 Просто попроси.
- «Проверь контакты всех заведений в маршруте» → ассистент пройдёт по списку и покажет, у кого не хватает доказательств.
- «Откуда взялся этот рейтинг?» → ассистент назовёт источник и дату проверки либо уберёт цифру, если источника нет.
9. Карты и погода: порядок координат решает всё
Метка, маршрут дня и прогноз без единого ключа доступа
Ключевая мысль: координаты и погода
Во внешний мир готовый файл выходит только в двух местах — за картами и за погодой, — и ни там, ни там не нужен ключ доступа.
Карты — это просто ссылки. У Яндекс.Карт две схемы, и координаты в них идут в разном порядке — это главная ловушка раздела:
- метка одной точки: ?pt=долгота,широта — сначала долгота;
- маршрут дня: ?rtext=широта,долгота~широта,долгота — сначала широта, а точки разделяет тильда; тип пути задаёт rtt (pd пешком, auto на машине, mt на транспорте).
Перепутанный порядок не даёт ошибки: ссылка открывается и показывает уверенно неверное место — Мира однажды получила вместо Кремля точку в Индийском океане. Поэтому в чек-листе валидации есть отдельная строка про порядок координат.
Погода — запрос к Open-Meteo прямо со страницы. Сервис открыт для запросов из браузера и не требует ключа, поэтому файл остаётся самодостаточным: никакого сервера, никакого секрета внутри. Совет по одежде страница считает сама, по температуре и осадкам, — отдельного запроса на это нет. Нет сети — блок погоды аккуратно исчезает, остальное работает.
Компромиссы. Сильная сторона: ни ключей, ни серверной части, ни расходов — файл живёт сам по себе. Слабая: ты привязан к Яндекс.Картам, а это осмысленный выбор для России и слабый для, скажем, Лиссабона.
💬 Просто попроси.
- «Проверь ссылки на карты в маршруте» → ассистент сверит порядок координат в метках и маршрутах дней.
- «Сделай маршрут дня пешеходным» → ассистент выставит rtt=pd в ссылке маршрута.
10. Валидация: чек-лист, который решает — готово или нет
Семь проверок последнего шага и что каждая ловит
Ключевая мысль: валидация маршрута
Пятый шаг конвейера — валидация маршрута. Это не финальное «ну вроде нормально», а список конкретных проверок, каждая из которых ловит свой класс ошибок, уже случавшихся на практике.
Что проверяется:
1. Каждая точка — есть координаты, ссылка-метка, стоимость и отметка о необходимости брони.
2. Каждое названное заведение — адрес, сайт или телефон, ссылка на отзывы и дата проверки.
3. Каждый день — рабочая ссылка на маршрут по всем точкам дня, блок погоды и совет по одежде.
4. Ограничения — соблюдены в каждом выборе, без исключений «ну почти».
5. Разнообразие — в поездке есть экскурсии, музеи, прогулки, смотровые площадки, вода и местная кухня; план целиком из музеев не проходит.
6. Мобильность — открывается одной рукой, нет горизонтальной прокрутки, карточки раскрываются.
7. Дни приезда и отъезда — укладываются в реальные транспортные окна.
Валидация решает исход. Провал пункта — это не примечание в конце, а причина вернуться и переделать. Мира узнаёт здесь тот же приём, что и в конвейере разработки функций: дешёвая машинная проверка стоит в конце и ловит то, что человек уже устал замечать.
Компромиссы. Сильная сторона: проверка объективна и одинакова каждый раз, усталость на неё не влияет. Слабая: чек-лист проверяет наличие и форму, а не вкус — скучный, но формально полный маршрут он пропустит.
💬 Просто попроси.
- «Прогони валидацию маршрута и покажи, что не сходится» → ассистент пройдёт по семи пунктам и назовёт провалы.
- «Почему маршрут не принят?» → ассистент укажет конкретный пункт чек-листа и точку, на которой он сломался.
11. Самообучение исследовательского навыка
Как навык исследования накапливает уроки о методе и почему хранилище отдельное
Ключевая мысль: самообучение навыка
У навыка исследования есть необязательная надстройка — самообучение. Мира замечает её не сразу, потому что без неё всё работает точно так же.
Механика простая. Если в системе установлен @dzhechkov/harness-cli, навык в начале исследования вспоминает ранее записанные уроки о методе — как искать, каким источникам верить, где обычно ошибался, — и записывает новые в четырёх заранее названных точках прогона. Инструмент подхватывается, если он есть, но не требуется: если его нет, навык один раз честно сообщает об этом и работает как обычно.
Самое интересное — устройство хранилища. Уроки складываются в отдельное хранилище проекта, а не в общее. Чтение идёт из обоих, запись — только в отдельное. Получается односторонняя мембрана: инженерные уроки приходят внутрь и помогают, а то, что связано с чувствительной темой, наружу не уходит.
Есть и честно очерченная граница проверки. Формальный контроль отклоняет то, что похоже на идентификатор человека: адрес почты, телефон, номер записи. Но он не решает, о чём урок — о методе или о человеке, — и прямо об этом предупреждает. Это решение агента по протоколу записи уроков, а не работа фильтра.
Компромиссы. Сильная сторона: качество исследования растёт от прогона к прогону, и надстройка ничего не ломает своим отсутствием. Слабая: формальный фильтр — не гарантия приватности, ответственность за содержание урока остаётся на том, кто его записывает.
💬 Просто попроси.
- «Включено ли самообучение исследования?» → ассистент проверит наличие harness-cli и скажет, работают ли уроки.
- «Какие уроки о методе поиска уже накоплены?» → ассистент выберет уроки из хранилища и перескажет главные.
12. Границы: когда trip-planner не тот инструмент
Три соседних навыка и честный список ограничений пакета
Ключевая мысль: границы применения
Инструмент, у которого нет описанных границ, обычно применяют не по назначению. У trip-planner границы названы прямо в описании навыка, и Мира заканчивает курс именно ими.
Когда нужен не он, а сосед:
- исследование без дат и логистики («что вообще интересного в Казани?») → навык goap-research-ed25519 напрямую: он ищет и проверяет, но не раскладывает по дням;
- обычная информационная страница, не маршрут → навык frontend-design;
- учебный сайт или курс → генератор учебных сайтов, а для расшифровки беседы есть свой отдельный генератор.
Честные ограничения самого пакета:
1. результат — снимок на момент сборки: часы работы и цены сами не обновятся;
2. карты завязаны на Яндекс — за пределами России польза заметно падает;
3. качество плана целиком зависит от шага исследования: не нашлись проверенные контакты — заведение выпадает, даже если оно прекрасное;
4. строгие ограничения в маленьком городе могут оставить очень узкий выбор;
5. единственный живой запрос страницы — погода, всё остальное зафиксировано в файле.
Вывод, который стоит унести с собой. Ценность пакета не в том, что он «знает города», а в том, что он отказывается врать: не выдумывает координаты, не смягчает ограничения молча и не выдаёт непроверенное за проверенное. Именно поэтому итоговому файлу можно доверять в дороге.
💬 Просто попроси.
- «Мне нужен просто обзор города без дат» → ассистент предложит навык исследования вместо trip-planner.
- «Обнови маршрут: часы музея изменились» → ассистент перезапустит шаги исследования и сборки для этой точки.
Частые вопросы
- Нужен ли ключ доступа к картам или погоде?
Нет. Яндекс.Карты открываются обычной ссылкой, а прогноз запрашивается у Open-Meteo прямо из страницы — сервис не требует ключа. Поэтому готовый файл остаётся самодостаточным: внутри него нет ни одного секрета.
- Что будет, если я не укажу время приезда?
Навык остановится и спросит. Придуманное время сдвинуло бы весь первый день, а обнаружилось бы это уже на вокзале — поэтому обязательные поля брифа не додумываются.
- Можно ли пользоваться пакетом не в Claude Code?
Да. Поставь общий установщик командой npm install -g @dzhechkov/harness-cli и выполни dz install @dzhechkov/trip-planner --target hermes. Канонический SKILL.md остаётся прежним — он лишь проецируется в каталог другого ассистента.
- Почему из плана пропало заведение, которое мне советовали?
Две обычные причины: оно нарушило ограничение (алкоголь, вегетарианство, бюджет, дети) либо у него не нашлось обязательных доказательств — адреса, официального контакта и отдельной ссылки на отзывы с датой проверки. В обоих случаях кандидат заменяется, а не помечается сноской.
- Файл будет обновляться, если у музея изменятся часы работы?
Нет, это снимок на момент сборки. Обновление — это повторный прогон шагов исследования и сборки. Такова цена самодостаточности: файл работает офлайн именно потому, что все данные лежат внутри него.
- Что делает doctor и когда он нужен?
Он читает манифест .trip-planner.json и проверяет, что все записанные файлы на месте. Он нужен, когда команда /trip-planner перестала находиться или навыки начали вести себя странно. Лечится повторной установкой с флагом --force.