Files
Learn_System/CLAUDE.md
T

7.4 KiB
Raw Blame History

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 / localStorage lab-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.