@rt-tools/agent-kit 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +1 -0
  2. package/assets/agents/rules-reviewer.md +83 -0
  3. package/assets/checks/check-dupes.mjs +66 -6
  4. package/assets/checks/check-specs.mjs +100 -15
  5. package/assets/checks/rt-kit-checks.config.mjs +9 -0
  6. package/assets/commands/feedback.md +95 -0
  7. package/assets/commands/rules-review.md +98 -0
  8. package/assets/commands/skill-curator.md +39 -22
  9. package/assets/docs/GLOSSARY.md +21 -20
  10. package/assets/hooks/reuse-first-guard.sh +16 -2
  11. package/assets/hooks/skill-gate.sh +1 -1
  12. package/assets/hooks/task-flow-guard.sh +16 -2
  13. package/assets/hooks/waiting-turn-guard.sh +87 -0
  14. package/assets/laws/delivery.md +28 -0
  15. package/assets/laws/project-documentation.md +18 -0
  16. package/assets/laws/work-conduct.md +16 -0
  17. package/assets/patterns/git-workflow-commit.azure.md +74 -2
  18. package/assets/patterns/git-workflow-commit.github.md +75 -2
  19. package/assets/patterns/git-workflow-commit.gitlab.md +75 -4
  20. package/assets/patterns/git-workflow-docker.md +30 -0
  21. package/assets/patterns/task-flow-close.md +154 -47
  22. package/assets/patterns/task-flow-handoff.md +1 -1
  23. package/assets/patterns/task-flow-resume.md +3 -3
  24. package/assets/patterns/task-flow-start.md +32 -5
  25. package/assets/rules/angular-patterns.md +22 -0
  26. package/assets/rules/api-layer.md +25 -0
  27. package/assets/rules/browser-verification.md +32 -0
  28. package/assets/rules/component-structure.md +21 -0
  29. package/assets/rules/dependencies.md +22 -0
  30. package/assets/rules/doc-style.md +24 -0
  31. package/assets/rules/entity-conventions.needs-admin.md +21 -0
  32. package/assets/rules/entity-models.md +21 -0
  33. package/assets/rules/git-workflow.azure.md +50 -1
  34. package/assets/rules/git-workflow.github.md +48 -2
  35. package/assets/rules/git-workflow.gitlab.md +49 -1
  36. package/assets/rules/lib-layers.md +25 -0
  37. package/assets/rules/lists.md +27 -0
  38. package/assets/rules/navigation.md +21 -0
  39. package/assets/rules/observability.needs-app.md +23 -0
  40. package/assets/rules/permissions.md +23 -0
  41. package/assets/rules/platform-access.md +21 -0
  42. package/assets/rules/reuse-first.md +20 -0
  43. package/assets/rules/seo.md +19 -0
  44. package/assets/rules/shared-code.md +19 -0
  45. package/assets/rules/spec-driven.md +32 -0
  46. package/assets/rules/styling-bem.md +19 -0
  47. package/assets/rules/task-flow.md +107 -17
  48. package/assets/rules/testing.md +31 -0
  49. package/assets/rules/translations.md +21 -0
  50. package/assets/rules/typescript-conventions.md +21 -0
  51. package/assets/samples/specs/_template/spec.md +83 -0
  52. package/assets/samples/tasks/_template/grill.md +28 -0
  53. package/assets/samples/tasks/_template/plan.md +39 -0
  54. package/assets/samples/tasks/_template/progress.md +23 -0
  55. package/assets/skills/agent-kit.md +16 -2
  56. package/assets/templates/rule.md +31 -2
  57. package/lib/commands.d.ts.map +1 -1
  58. package/lib/commands.js +1 -0
  59. package/lib/commands.js.map +1 -1
  60. package/lib/config.d.ts +10 -1
  61. package/lib/config.d.ts.map +1 -1
  62. package/lib/config.js +4 -0
  63. package/lib/config.js.map +1 -1
  64. package/package.json +1 -1
  65. package/rt-tools-agent-kit-0.8.3.tgz +0 -0
  66. package/rt-tools-agent-kit-0.8.2.tgz +0 -0
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAkBjC,MAAM,CAAC,MAAM,KAAK,GAAqB;IACnC,MAAM;IACN,OAAO;IACP,UAAU;IACV,QAAQ;IACR,OAAO;IACP,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,WAAW;IACX,WAAW;IACX,MAAM;CACT,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAE7E,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAW,UAAU,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAW,mBAAmB,CAAC;AAmD1D,MAAM,CAAC,MAAM,WAAW,GAAW,qBAAqB,CAAC;AACzD,qGAAqG;AACrG,MAAM,CAAC,MAAM,UAAU,GAAW,gBAAgB,CAAC;AACnD,MAAM,CAAC,MAAM,aAAa,GAAW,0BAA0B,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAW,kBAAkB,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,YAAY,GAAW,yBAAyB,CAAC;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAW,aAAa,CAAC;AACnD,MAAM,CAAC,MAAM,YAAY,GAAW,YAAY,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoC;IAC3D,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,gBAAgB;IAC1B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,eAAe;IACtB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,gBAAgB;IACxB,QAAQ,EAAE,kBAAkB;IAC5B,SAAS,EAAE,mBAAmB;IAC9B,SAAS,EAAE,0BAA0B;IACrC,IAAI,EAAE,MAAM;CACf,CAAC;AAEF,MAAM,OAAO,WAAY,SAAQ,KAAK;CAAG;AAEzC,MAAM,QAAQ,GAAyD,CAAC,KAAc,EAAoC,EAAE,CACxH,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEzE,SAAS,SAAS,CAAC,KAAc,EAAE,KAAa;IAC5C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,WAAW,CAAC,GAAG,KAAK,qCAAqC,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,WAAW,CAAC,GAAG,KAAK,IAAI,GAAG,oBAAoB,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,iGAAiG;AACjG,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa;IACzC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,WAAW,CAAC,GAAG,KAAK,oBAAoB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa;IACzC,MAAM,IAAI,GAAY,KAAK,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,KAAc,EAAW,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,WAAW,CAAC,GAAG,KAAK,6CAA6C,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,IAAgB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,MAAM,IAAI,WAAW,CAAC,GAAG,WAAW,+BAAgC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,WAAW,CAAC,GAAG,WAAW,oBAAoB,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,GAAG,cAAc,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;IACpG,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAa,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,WAAW,CAAC,UAAU,IAAI,qCAAqC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAsB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAsB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAE5D,4FAA4F;IAC5F,8EAA8E;IAC9E,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO;QACH,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE;QACvD,MAAM,EAAE,MAA+B;QACvC,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;QAChD,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;QAC9B,qFAAqF;QACrF,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,KAAK,KAAK;QACjC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QACpC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACjC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,IAAI,uBAAuB;KACpF,CAAC;AACN,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,IAAI,CAAC;QACD,OAAO,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YAC/B,MAAM,KAAK,CAAC;QAChB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC","sourcesContent":["/**\n * Конфиг проекта — `.claude/rt-kit.json`.\n *\n * Всё, что пакет не может знать сам: значения для дырок, куда класть каждый род ресурса и от\n * чего проект отказался. Конфиг лежит в дереве проекта и коммитится: раскладка обязана\n * повторяться на чужой машине без вопросов, иначе разложенное расходится между разработчиками.\n */\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/** Род ресурса. Он же имя каталога в `assets/` пакета и ключ раскладки. */\nexport type TKind =\n | 'laws'\n | 'rules'\n | 'patterns'\n | 'skills'\n | 'hooks'\n | 'defaults'\n | 'checks'\n | 'agents'\n | 'commands'\n | 'workflows'\n | 'templates'\n /** Документы дерева, которые читает и человек, и агент: словарь проекта. */\n | 'docs';\n\nexport const KINDS: readonly TKind[] = [\n 'laws',\n 'rules',\n 'patterns',\n 'skills',\n 'hooks',\n 'defaults',\n 'checks',\n 'agents',\n 'commands',\n 'workflows',\n 'templates',\n 'docs',\n];\n\n/**\n * Роды, которые ложатся не файлом в каталог, а каталогом по имени ресурса: скил читается как\n * `<имя>/SKILL.md`, и рядом с ним лежит то, что пишет проект.\n *\n * `skills` — скил, у которого нет закона над собой: он не про то, что должно быть верно в\n * продукте, а про то, как здесь делается работа. Правилом его называть нельзя — тогда придётся\n * выдумать ему закон, — а паттерном тем более: паттерн стоит при правиле.\n */\nexport const SKILL_KINDS: readonly TKind[] = ['rules', 'patterns', 'skills'];\n\n/** Имя файла скила: так его ищет агент, и другого имени у него быть не может. */\nexport const SKILL_FILE: string = 'SKILL.md';\n\n/**\n * Файл-компаньон правила: чем названо в этом дереве то, о чём правило говорит приёмом.\n *\n * Пакет знает приём, но не знает ни путей, ни имён — их пишет проект. Черновик кладётся один\n * раз и дальше не сверяется: это единственный файл раскладки, который принадлежит проекту.\n */\nexport const COMPANION_FILE: string = 'implementation.md';\n\nexport interface IConfig {\n /** Значения дырок `{{имя}}`. */\n readonly vars: Readonly<Record<string, string>>;\n /** Куда класть каждый род ресурса, путями от корня проекта. */\n readonly layout: Readonly<Record<TKind, string>>;\n /**\n * Ресурсы, которые проект выбрал, идентификаторами: `laws/access.md`. Пусто — берётся всё.\n * Ограничивает только те роды, которые сам называет; как именно — `isChosen`.\n */\n readonly only: readonly string[];\n /** Ресурсы, от которых проект отказался, идентификаторами: `laws/application/money.md`. */\n readonly skip: readonly string[];\n /**\n * Выбор проекта по осям различия: `{ \"host\": \"gitlab\" }`. Оси объявлены пакетом в\n * `assets/variants.json`, а ресурс с вариантом в имени берётся, только если проект выбрал\n * его значение; как именно — `isChosen`.\n */\n readonly variants: Readonly<Record<string, string>>;\n /**\n * Что у дерева есть: `[\"packages\", \"app\"]`. Свойства объявлены пакетом в `assets/traits.json`,\n * а ресурс, требующий свойства именем файла, дереву без него не кладётся вовсе — ни сам, ни\n * черновик его компаньона. Пусто — дерево о себе ничего не сказало, и помеченного не получает.\n */\n readonly has: readonly string[];\n /**\n * Пишут ли гарды наблюдения о слое правил. Умолчание — да; выключает дерево, и целиком, а\n * не частями. Ключ читают двое: сводка — отсюда, гард — тем же именем прямо из файла, потому\n * что разборщика конфига у него нет.\n */\n readonly observe: boolean;\n /**\n * Адрес приёма, куда уезжает груз: `https://…`. Пусто — отправлять некуда, и отправка\n * отказывает вместо молчания. Зашитый в код адрес назвал бы чужое дерево в текстах пакета.\n */\n readonly intake: string;\n /**\n * Файл с токеном дерева — путь от корня дерева или от домашнего каталога (`~/…`). Сам токен\n * в конфиге не лежит: конфиг коммитится, а токен обязан остаться вне истории.\n */\n readonly token: string;\n /**\n * Признак дерева, когда удалённого репозитория нет. При нём — считается из адреса\n * репозитория: две рабочие копии одного репозитория обязаны дать один признак.\n */\n readonly tree: string;\n /** Где дерево держит разборы происшествий. Путь от корня дерева. */\n readonly postmortems: string;\n}\n\nexport const CONFIG_PATH: string = '.claude/rt-kit.json';\n/** Каталог, в котором дерево держит своё при пакете: надстройки, умолчания, свою карту и профиль. */\nexport const RT_KIT_DIR: string = '.claude/rt-kit';\nexport const OVERRIDES_DIR: string = '.claude/rt-kit/overrides';\n\n/**\n * Где разборы происшествий лежат, когда конфиг не сказал иначе. Роды ресурсов сюда не годятся:\n * разборы пишет дерево про себя, пакет их не раскладывает и не сверяет.\n */\nexport const DEFAULT_POSTMORTEMS_DIR: string = 'docs/postmortems';\n\n/**\n * Карта «что правится — какое правило» и профиль дерева: команды, стенды, пары «правка —\n * документ». Оба лежат в двух видах, и это не дублирование, а разделение ответственности.\n *\n * Умолчание везёт пакет: проекты этой мастерской устроены одинаково — Nx, те же расширения, те\n * же имена каталогов, — и переписывать одну и ту же карту в каждом дереве заново значило бы\n * заводить пятнадцать её редакций, расходящихся молча. Оно разложено, под шапкой, и правится\n * не на месте.\n *\n * Надстройку пишет проект, и она необязательна: витрина, свой род файлов, другой запускатель\n * тестов есть не у всех. Объявленная в ней функция замещает умолчание целиком и вправе позвать\n * его обратно суффиксом `_default` — так дерево дописывает своё, не теряя общего.\n */\nexport const DEFAULTS_DIR: string = '.claude/rt-kit/defaults';\nexport const GATE_MAP_FILE: string = 'gate-map.sh';\nexport const PROFILE_FILE: string = 'project.sh';\n\n/**\n * Умолчания раскладки. Это не единственно возможные пути, но менять их без нужды не стоит:\n * агент ищет законы в `docs/constitution`, потому что так написано в правилах, которые пакет\n * же и везёт.\n */\nexport const DEFAULT_LAYOUT: Readonly<Record<TKind, string>> = {\n laws: 'docs/constitution',\n rules: '.claude/skills',\n patterns: '.claude/skills',\n skills: '.claude/skills',\n hooks: '.claude/hooks',\n defaults: DEFAULTS_DIR,\n checks: 'tools',\n agents: '.claude/agents',\n commands: '.claude/commands',\n workflows: '.claude/workflows',\n templates: '.claude/rt-kit/templates',\n docs: 'docs',\n};\n\nexport class ConfigError extends Error {}\n\nconst isRecord: (value: unknown) => value is Record<string, unknown> = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction stringMap(value: unknown, where: string): Record<string, string> {\n if (value === undefined) {\n return {};\n }\n if (!isRecord(value)) {\n throw new ConfigError(`${where}: ожидается объект «имя — значение»`);\n }\n const result: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') {\n throw new ConfigError(`${where}.${key}: ожидается строка`);\n }\n result[key] = entry;\n }\n\n return result;\n}\n\n/** Строковый ключ конфига. Ключа нет — пустая строка: значение необязательное у всех четырёх. */\nfunction textOf(value: unknown, where: string): string {\n if (value === undefined || value === null) {\n return '';\n }\n if (typeof value !== 'string') {\n throw new ConfigError(`${where}: ожидается строка`);\n }\n\n return value.trim();\n}\n\nfunction idList(value: unknown, where: string): readonly string[] {\n const list: unknown = value ?? [];\n if (!Array.isArray(list) || list.some((entry: unknown): boolean => typeof entry !== 'string')) {\n throw new ConfigError(`${where}: ожидается список идентификаторов ресурсов`);\n }\n\n return list as string[];\n}\n\nexport function parseConfig(text: string): IConfig {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (error: unknown) {\n throw new ConfigError(`${CONFIG_PATH} — не разбирается как JSON: ${(error as Error).message}`);\n }\n if (!isRecord(raw)) {\n throw new ConfigError(`${CONFIG_PATH}: ожидается объект`);\n }\n\n const layout: Record<string, string> = { ...DEFAULT_LAYOUT, ...stringMap(raw['layout'], 'layout') };\n for (const kind of Object.keys(layout)) {\n if (!KINDS.includes(kind as TKind)) {\n throw new ConfigError(`layout.${kind}: такого рода ресурсов нет — есть ${KINDS.join(', ')}`);\n }\n }\n\n const only: readonly string[] = idList(raw['only'], 'only');\n const skip: readonly string[] = idList(raw['skip'], 'skip');\n\n // Пути раскладки — тоже значения проекта, и пакет их уже знает. Требовать их вторым списком\n // значило бы держать одно и то же в двух местах: расходятся такие пары молча.\n const derived: Record<string, string> = {};\n for (const kind of KINDS) {\n derived[`${kind.replace(/s$/, '')}sDir`] = layout[kind];\n }\n\n return {\n vars: { ...derived, ...stringMap(raw['vars'], 'vars') },\n layout: layout as Record<TKind, string>,\n only,\n skip,\n variants: stringMap(raw['variants'], 'variants'),\n has: idList(raw['has'], 'has'),\n // Выключателем считается только явное «нет»: ключа нет — запись идёт, как и у гарда.\n observe: raw['observe'] !== false,\n intake: textOf(raw['intake'], 'intake'),\n token: textOf(raw['token'], 'token'),\n tree: textOf(raw['tree'], 'tree'),\n postmortems: textOf(raw['postmortems'], 'postmortems') || DEFAULT_POSTMORTEMS_DIR,\n };\n}\n\n/** Конфиг проекта; его отсутствие — не отказ, а повод сказать про `agent-kit init`. */\nexport function readConfig(root: string): IConfig | null {\n try {\n return parseConfig(readFileSync(join(root, CONFIG_PATH), 'utf8'));\n } catch (error: unknown) {\n if (error instanceof ConfigError) {\n throw error;\n }\n\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Конфиг проекта — `.claude/rt-kit.json`.\n *\n * Всё, что пакет не может знать сам: значения для дырок, куда класть каждый род ресурса и от\n * чего проект отказался. Конфиг лежит в дереве проекта и коммитится: раскладка обязана\n * повторяться на чужой машине без вопросов, иначе разложенное расходится между разработчиками.\n */\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/** Род ресурса. Он же имя каталога в `assets/` пакета и ключ раскладки. */\nexport type TKind =\n | 'laws'\n | 'rules'\n | 'patterns'\n | 'skills'\n | 'hooks'\n | 'defaults'\n | 'checks'\n | 'agents'\n | 'commands'\n | 'workflows'\n | 'templates'\n /** Документы дерева, которые читает и человек, и агент: словарь проекта. */\n | 'docs'\n /**\n * Образцы, которые копируют в рабочий файл и заполняют: папка задачи, спек домена.\n *\n * От шаблонов отличаются читателем и местом. Шаблон ложится в каталог слоя правил, и с него\n * пишут ресурс этого слоя; образец ложится туда, где идёт работа, и копирует его тот, кто\n * работу ведёт. Одним родом их не свести: дерево вправе отказаться от одних, оставив\n * другие, и назвать им разные каталоги.\n */\n | 'samples';\n\nexport const KINDS: readonly TKind[] = [\n 'laws',\n 'rules',\n 'patterns',\n 'skills',\n 'hooks',\n 'defaults',\n 'checks',\n 'agents',\n 'commands',\n 'workflows',\n 'templates',\n 'docs',\n 'samples',\n];\n\n/**\n * Роды, которые ложатся не файлом в каталог, а каталогом по имени ресурса: скил читается как\n * `<имя>/SKILL.md`, и рядом с ним лежит то, что пишет проект.\n *\n * `skills` — скил, у которого нет закона над собой: он не про то, что должно быть верно в\n * продукте, а про то, как здесь делается работа. Правилом его называть нельзя — тогда придётся\n * выдумать ему закон, — а паттерном тем более: паттерн стоит при правиле.\n */\nexport const SKILL_KINDS: readonly TKind[] = ['rules', 'patterns', 'skills'];\n\n/** Имя файла скила: так его ищет агент, и другого имени у него быть не может. */\nexport const SKILL_FILE: string = 'SKILL.md';\n\n/**\n * Файл-компаньон правила: чем названо в этом дереве то, о чём правило говорит приёмом.\n *\n * Пакет знает приём, но не знает ни путей, ни имён — их пишет проект. Черновик кладётся один\n * раз и дальше не сверяется: это единственный файл раскладки, который принадлежит проекту.\n */\nexport const COMPANION_FILE: string = 'implementation.md';\n\nexport interface IConfig {\n /** Значения дырок `{{имя}}`. */\n readonly vars: Readonly<Record<string, string>>;\n /** Куда класть каждый род ресурса, путями от корня проекта. */\n readonly layout: Readonly<Record<TKind, string>>;\n /**\n * Ресурсы, которые проект выбрал, идентификаторами: `laws/access.md`. Пусто — берётся всё.\n * Ограничивает только те роды, которые сам называет; как именно — `isChosen`.\n */\n readonly only: readonly string[];\n /** Ресурсы, от которых проект отказался, идентификаторами: `laws/application/money.md`. */\n readonly skip: readonly string[];\n /**\n * Выбор проекта по осям различия: `{ \"host\": \"gitlab\" }`. Оси объявлены пакетом в\n * `assets/variants.json`, а ресурс с вариантом в имени берётся, только если проект выбрал\n * его значение; как именно — `isChosen`.\n */\n readonly variants: Readonly<Record<string, string>>;\n /**\n * Что у дерева есть: `[\"packages\", \"app\"]`. Свойства объявлены пакетом в `assets/traits.json`,\n * а ресурс, требующий свойства именем файла, дереву без него не кладётся вовсе — ни сам, ни\n * черновик его компаньона. Пусто — дерево о себе ничего не сказало, и помеченного не получает.\n */\n readonly has: readonly string[];\n /**\n * Пишут ли гарды наблюдения о слое правил. Умолчание — да; выключает дерево, и целиком, а\n * не частями. Ключ читают двое: сводка — отсюда, гард — тем же именем прямо из файла, потому\n * что разборщика конфига у него нет.\n */\n readonly observe: boolean;\n /**\n * Адрес приёма, куда уезжает груз: `https://…`. Пусто — отправлять некуда, и отправка\n * отказывает вместо молчания. Зашитый в код адрес назвал бы чужое дерево в текстах пакета.\n */\n readonly intake: string;\n /**\n * Файл с токеном дерева — путь от корня дерева или от домашнего каталога (`~/…`). Сам токен\n * в конфиге не лежит: конфиг коммитится, а токен обязан остаться вне истории.\n */\n readonly token: string;\n /**\n * Признак дерева, когда удалённого репозитория нет. При нём — считается из адреса\n * репозитория: две рабочие копии одного репозитория обязаны дать один признак.\n */\n readonly tree: string;\n /** Где дерево держит разборы происшествий. Путь от корня дерева. */\n readonly postmortems: string;\n}\n\nexport const CONFIG_PATH: string = '.claude/rt-kit.json';\n/** Каталог, в котором дерево держит своё при пакете: надстройки, умолчания, свою карту и профиль. */\nexport const RT_KIT_DIR: string = '.claude/rt-kit';\nexport const OVERRIDES_DIR: string = '.claude/rt-kit/overrides';\n\n/**\n * Где разборы происшествий лежат, когда конфиг не сказал иначе. Роды ресурсов сюда не годятся:\n * разборы пишет дерево про себя, пакет их не раскладывает и не сверяет.\n */\nexport const DEFAULT_POSTMORTEMS_DIR: string = 'docs/postmortems';\n\n/**\n * Карта «что правится — какое правило» и профиль дерева: команды, стенды, пары «правка —\n * документ». Оба лежат в двух видах, и это не дублирование, а разделение ответственности.\n *\n * Умолчание везёт пакет: проекты этой мастерской устроены одинаково — Nx, те же расширения, те\n * же имена каталогов, — и переписывать одну и ту же карту в каждом дереве заново значило бы\n * заводить пятнадцать её редакций, расходящихся молча. Оно разложено, под шапкой, и правится\n * не на месте.\n *\n * Надстройку пишет проект, и она необязательна: витрина, свой род файлов, другой запускатель\n * тестов есть не у всех. Объявленная в ней функция замещает умолчание целиком и вправе позвать\n * его обратно суффиксом `_default` — так дерево дописывает своё, не теряя общего.\n */\nexport const DEFAULTS_DIR: string = '.claude/rt-kit/defaults';\nexport const GATE_MAP_FILE: string = 'gate-map.sh';\nexport const PROFILE_FILE: string = 'project.sh';\n\n/**\n * Умолчания раскладки. Это не единственно возможные пути, но менять их без нужды не стоит:\n * агент ищет законы в `docs/constitution`, потому что так написано в правилах, которые пакет\n * же и везёт.\n */\nexport const DEFAULT_LAYOUT: Readonly<Record<TKind, string>> = {\n laws: 'docs/constitution',\n rules: '.claude/skills',\n patterns: '.claude/skills',\n skills: '.claude/skills',\n hooks: '.claude/hooks',\n defaults: DEFAULTS_DIR,\n checks: 'tools',\n agents: '.claude/agents',\n commands: '.claude/commands',\n workflows: '.claude/workflows',\n templates: '.claude/rt-kit/templates',\n docs: 'docs',\n // Внутри рода путь повторяет раскладку дерева — папки задач и спеки, — поэтому одного\n // умолчания хватает всем образцам сразу.\n samples: 'docs',\n};\n\nexport class ConfigError extends Error {}\n\nconst isRecord: (value: unknown) => value is Record<string, unknown> = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction stringMap(value: unknown, where: string): Record<string, string> {\n if (value === undefined) {\n return {};\n }\n if (!isRecord(value)) {\n throw new ConfigError(`${where}: ожидается объект «имя — значение»`);\n }\n const result: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') {\n throw new ConfigError(`${where}.${key}: ожидается строка`);\n }\n result[key] = entry;\n }\n\n return result;\n}\n\n/** Строковый ключ конфига. Ключа нет — пустая строка: значение необязательное у всех четырёх. */\nfunction textOf(value: unknown, where: string): string {\n if (value === undefined || value === null) {\n return '';\n }\n if (typeof value !== 'string') {\n throw new ConfigError(`${where}: ожидается строка`);\n }\n\n return value.trim();\n}\n\nfunction idList(value: unknown, where: string): readonly string[] {\n const list: unknown = value ?? [];\n if (!Array.isArray(list) || list.some((entry: unknown): boolean => typeof entry !== 'string')) {\n throw new ConfigError(`${where}: ожидается список идентификаторов ресурсов`);\n }\n\n return list as string[];\n}\n\nexport function parseConfig(text: string): IConfig {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (error: unknown) {\n throw new ConfigError(`${CONFIG_PATH} — не разбирается как JSON: ${(error as Error).message}`);\n }\n if (!isRecord(raw)) {\n throw new ConfigError(`${CONFIG_PATH}: ожидается объект`);\n }\n\n const layout: Record<string, string> = { ...DEFAULT_LAYOUT, ...stringMap(raw['layout'], 'layout') };\n for (const kind of Object.keys(layout)) {\n if (!KINDS.includes(kind as TKind)) {\n throw new ConfigError(`layout.${kind}: такого рода ресурсов нет — есть ${KINDS.join(', ')}`);\n }\n }\n\n const only: readonly string[] = idList(raw['only'], 'only');\n const skip: readonly string[] = idList(raw['skip'], 'skip');\n\n // Пути раскладки — тоже значения проекта, и пакет их уже знает. Требовать их вторым списком\n // значило бы держать одно и то же в двух местах: расходятся такие пары молча.\n const derived: Record<string, string> = {};\n for (const kind of KINDS) {\n derived[`${kind.replace(/s$/, '')}sDir`] = layout[kind];\n }\n\n return {\n vars: { ...derived, ...stringMap(raw['vars'], 'vars') },\n layout: layout as Record<TKind, string>,\n only,\n skip,\n variants: stringMap(raw['variants'], 'variants'),\n has: idList(raw['has'], 'has'),\n // Выключателем считается только явное «нет»: ключа нет — запись идёт, как и у гарда.\n observe: raw['observe'] !== false,\n intake: textOf(raw['intake'], 'intake'),\n token: textOf(raw['token'], 'token'),\n tree: textOf(raw['tree'], 'tree'),\n postmortems: textOf(raw['postmortems'], 'postmortems') || DEFAULT_POSTMORTEMS_DIR,\n };\n}\n\n/** Конфиг проекта; его отсутствие — не отказ, а повод сказать про `agent-kit init`. */\nexport function readConfig(root: string): IConfig | null {\n try {\n return parseConfig(readFileSync(join(root, CONFIG_PATH), 'utf8'));\n } catch (error: unknown) {\n if (error instanceof ConfigError) {\n throw error;\n }\n\n return null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rt-tools/agent-kit",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Переносимый слой правил для агента: законы, хуки, проверки и агенты, раскладываемые в репозиторий одной командой",
5
5
  "author": "RT Team",
6
6
  "license": "Apache-2.0",
Binary file
Binary file