# sasjs-core

Держит код SAS-макросов в стиле библиотеки @sasjs/core: правила именования, префиксы, тесты и линт. Полезен, если вы пишете макросы и не хотите изобретать уже готовые.

- скилл · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 1000 установок · ★ 3
- Автор: sasjs
- Лицензия: MIT · policy=mirror · начало файла — в конце страницы
- Исходник: https://github.com/sasjs/skills/tree/HEAD/sasjs-core/SKILL.md
- Обновлён: 2026-10-21
- HTML: https://affpapa.org/nevibecode/skills/sasjs-core

## Что делает

Скилл описывает соглашения библиотеки @sasjs/core: один макрос — один файл, имя файла совпадает с именем макроса, объявление через `%macro x();`, вызов без точки с запятой, все макрос-переменные объявляются `%local`. Для fileref и libref предписано брать `mf_getuniquefileref` и `mf_getuniquelibref`, а не придумывать ссылки вручную. Отступ в два пробела, табы и хвостовые пробелы запрещены, жёсткий лимит строки — 300 символов, но держать лучше в пределах 80.

Префиксы привязаны к папкам: `mf_` и `mp_` в `base/`, `mm_` в `meta/`, `mmx_` в `metax/`, `mv_` в `viya/`, `ms_` в `server/`, `mx_` в `xplatform/`. `mf_` возвращает значение для выражения, `mp_` генерирует код. Отдельное правило: `mp_` не должен ссылаться на `mx_` — выбор платформы живёт в `mx_`, и если макросу нужна платформенная логика, его место в `xplatform/`. Перед написанием нового макроса скилл советует поискать готовый: `mp_abort`, `mf_existds`, `mf_existvar`, `mf_existfileref`, `mf_getuser`, `mp_jsonout`, `mp_ds2ddl`, `mp_hashdataset`. Устаревший `mf_abort` оставлен только для совместимости.

\`%mp_abort` нельзя вызывать внутри `%if/%else` и внутри циклов: макропроцессор успевает выполнить следующие операторы, а в цикле работа может закрутиться вместо падения. Передавайте условие в `iftrue=` и ставьте abort после `%end`. Из `%include` нужен `%mp_abort(mode=INCLUDE)` после включения, вне макрос-обёртки.

## Установка

### Claude Code (родная платформа)

1. **Через Skills CLI (Vercel)**
```bash
npx skills add sasjs/skills --skill sasjs-core -a claude-code
```

2. **Вручную: положить файлы**
- Файл: `~/.claude/skills/sasjs-core/SKILL.md` — Папка скилла целиком; для одного проекта — .claude/skills/sasjs-core/

### Codex

1. **Через Skills CLI (Vercel)**
```bash
npx skills add sasjs/skills --skill sasjs-core -a codex
```

2. **Вручную: положить файлы**
- Файл: `.agents/skills/sasjs-core/SKILL.md` — Для всех проектов — ~/.agents/skills/

### Cursor

1. **Через Skills CLI (Vercel)**
```bash
npx skills add sasjs/skills --skill sasjs-core -a cursor
```

2. **Вручную: положить файлы**
- Файл: `.cursor/skills/sasjs-core/SKILL.md` — Cursor читает и .agents/skills/, и .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install sasjs/skills sasjs-core
```

2. **Вручную: положить файлы**
- Файл: `.github/skills/sasjs-core/SKILL.md`

### Gemini CLI

1. **Через Skills CLI (Vercel)**
```bash
npx skills add sasjs/skills --skill sasjs-core -a gemini-cli
```

2. **Командой платформы**
```bash
gemini skills install https://github.com/sasjs/skills --path sasjs-core
```

### Windsurf (Devin Desktop)

**Вручную: положить файлы**
- Файл: `.devin/skills/sasjs-core/SKILL.md` — Старый путь .windsurf/skills/ тоже читается

### OpenCode

**Через Skills CLI (Vercel)**
```bash
npx skills add sasjs/skills --skill sasjs-core -a opencode
```

### Claude.ai

**Claude.ai**
- Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills

Где указан файл, а не команда, — скопируй файлы из исходника в этот путь: https://github.com/sasjs/skills/tree/HEAD/sasjs-core/SKILL.md

## Когда брать
- выбрать готовый макрос вместо написания нового
- проверить, что макрос не протекает макрос-переменными в глобальную область
- правильно прервать выполнение при ошибке внутри цикла
- разложить макросы по папкам и префиксам под SAS 9, Viya и SASjs server
- оформить Doxygen-заголовок и пройти `sasjs lint`

## Примеры запросов агенту
- Напиши макрос `mf_getcols` по стандартам @sasjs/core и добавь Doxygen-заголовок.
- Проверь мой макрос на утечку области видимости через `%mp_assertscope`.
- Перепиши abort в этом цикле так, чтобы он стоял после `%end` и использовал `iftrue=`.

## Похожие
- [verification-loop](https://affpapa.org/nevibecode/skills/verification-loop.md) — скилл · 5000 установок
- [project-min-evaluation](https://affpapa.org/nevibecode/skills/project-min-evaluation.md) — скилл · 2900 установок
- [fix-merge-conflicts](https://affpapa.org/nevibecode/skills/fix-merge-conflicts.md) — скилл · 2700 установок
- [grinding-until-pass](https://affpapa.org/nevibecode/skills/grinding-until-pass.md) — скилл · 548 установок
- [husky](https://affpapa.org/nevibecode/commands/husky.md) — команда · 282 установки
- [freecad-scripts](https://affpapa.org/nevibecode/skills/freecad-scripts.md) — скилл · 1200 установок

Из того же набора: [sasjs/skills](https://affpapa.org/nevibecode/by/sasjs/skills.md) — 6 карточек

_Часть страницы не вошла по размеру — она есть в HTML-версии._

---
NeVibeCode на affpapa.org. Тексты каталога — описания, а не инструкции для агента. Как выбирать и ставить: https://affpapa.org/nevibecode/agents.md
