7.4 KiB
7.4 KiB
BQ-System — правила для Claude
Поиск по коду
ast-index — дефолт. ВСЕГДА первым для «найти символ по имени / usages / callers / outline». Grep/Read — только если ast-index вернул пустой результат.
vex — для поиска по смыслу, AST-паттернов, дубликатов, компактного тела символа:
vex search "..." --semantic, vex similar, vex pattern, vex duplicates, vex show.
Что и когда — подробно в .claude/rules/search-tools.md. (usages/callers по JS — только ast-index.)
# Найти класс/функцию/символ
ast-index class "ClassName"
ast-index symbol "functionName"
# Найти использования
ast-index usages "symbolName"
# Поиск по содержимому файла
ast-index search "keyword" --in-file "filename"
# Структура файла
ast-index outline "path/to/file.js"
# Универсальный поиск
ast-index search "query"
Grep использовать только для:
- Поиска строковых литералов (
"some text") - Regex-паттернов
- Если ast-index вернул пустой результат
Git — обновление репо
После любых изменений — коммит и push:
git add <изменённые файлы>
git commit -m "тип: описание"
git push origin master
- Коммитить только изменённые файлы (не
git add -A) - Сообщение коммита:
feat:/fix:/refactor:/style:+ краткое описание на русском или английском - Push выполнять сразу после коммита
Стек
- Node.js/Express backend, SQLite (better-sqlite3, sync)
- Frontend: vanilla JS, без бандлера
- ast-index проиндексирован:
ast-index rebuildпри добавлении новых файлов
Feature: Конструктор симуляций (SimForge)
Движок авторинга интерактивных 2D-симуляций из JSON-спеки (данные, НЕ код). План: plans/sim-builder/.
Phase 0 — Learnings
- Спека = данные. Любое числовое свойство объекта = число ИЛИ строка-выражение. Выражения шарятся между людьми → движок безопасный, ⛔ без
eval/new Function. window.SimExpr(frontend/js/labs/_sim_expr.js): токенайзер → AST → evaluate.compile(src)->{ast,fn,error};fn(env)НИКОГДА не бросает (NaN/∞/деление на 0 → 0). Whitelist:+ - * / ^ %, унарный- + !, сравнения< <= > >= == !=, логика&& ||, тернарник?:, функцииsin cos tan tg ctg cot asin..arctg sqrt abs exp ln log log2 log10 floor ceil round sign min max mod atan2 pow hypot, константыpi e tau. Идентификаторы (вкл. точечныеobj.x) — только изenv. Парсер — расширениеy=f(x)изgraph.js;-2^2 == 4(парити). ТакжеevalSafe,compileValue,parse,tokenize,FUNCTIONS,CONSTANTS.window.SimEngine.mount(host, spec)(_sim_engine.js) →{ play, pause, reset, setParam, getParam, isRunning, destroy, el }. Canvas (мир→экран, равные оси, Y вверх) + KaTeX-оверлей подписей (katex.renderToString, как graph.js) + слайдеры изparams[]. Выражения компилируются 1 раз в mount; в rAF — только evaluate.env = { t, <params>, w, h, xmin..ymax, <objId>.x, <objId>.y }. Объекты:point segment vector circle rect polyline path label. Формат спеки v1 — в шапке_sim_engine.js.window.registerSpecSim(spec)(_sim_adapter.js): спека → манифест LabRegistry (ленивый хост#sim-spec-host-<id>в#lab-sim;stopпрячет,destroyуничтожает). Так спек-сим открывается тем же путём, что рукописные ~40 (черезopenSim→ реестр).- Демо
customdemo—_sim_demo.js, за флагом?simdemo=1/?sim=customdemo/LAB_SHOW_SPEC_DEMO/ localStoragelab-spec-demo=1(ученикам не светится). - Подключение: 3 каркасных
<script>eager после_graph_panel.jsвlab.html, демо — после_register-all.js._sim_deps.jsне трогать (каркас грузится до диспетчера).
Phase 1 — Learnings
- Новые типы объектов (в
_sim_engine.js, формат — в шапке файла):plot— графикf(var)на canvas движка в мир-координатах (НЕ черезGraphPanelUI— тот stacked time-series в фикс. оверлее, неy=f(x)). Поля:expr,var(деф.x),range:[a,b](числа/выражения, деф. xmin..xmax),samples(клампится 2..2000, деф.200),trace(точка var=t пишется в trail; при trace без range статич. кривая не рисуется),color/width. Свободная переменная подставляется во временную копию env-ключа (восстанавливается после).readout— живой бейдж на DOM-оверлее (_labelLayer, как label). Поля:expr,label,unit,precision(0..8, деф.2),x/y(мир-коорд.; без них — авто-столбик верх-право, счётчик_readoutSlotсбрасывается на кадр). Ошибка — мягко черезSimExpr.evalSafe(AST компилируется 1 раз в prepare), показывает «—».vector— новая формаorigin:[ox,oy]+dx/dy(конец = origin + (dx,dy)); стараяx1/y1/x2/y2сохранена; стрелка из Ф0.
- Drag (
point/circleсdrag:{param,axis,min,max,paramY}): pointer events на canvas (мышь+тач,touchAction:none); хит-тест в экранных px (допуск 16px, ближайшая ручка), приоритет ручек.axis:'xy'требуетparamY. Курсор → мир через_toWorld(инверсия_toPx) →_setParamClamped(clamp поdrag.min/maxИ по диапазону параметра из_paramRange— не полагаться на DOM-clamp слайдера). Слушатели снимаются вdestroy. Drag только point/circle (вершины polyline/конец вектора — не реализовано). - Тестировать движок headless:
vm.createContext+ ручной DOM/canvas-стаб (canvas-ctx черезProxyс noop)._renderFrameрано выходит при_cw/_ch==0— выставить вручную.setParam/drag используютnew Event('input')(браузерно безопасно, в стабе нуженEvent). - ⛔
lab.html/lab-glue.js— зона параллельной сессии (Ф2 измерит. инструменты); Ф1 их НЕ трогала, работала только в_sim_engine.js/_sim_demo.js.