@rt-tools/agent-kit 0.8.1 → 0.8.2
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.
- package/README.md +24 -19
- package/assets/agents/qa-engineer.md +1 -1
- package/assets/checks/board.github.mjs +56 -17
- package/assets/checks/check-board.github.mjs +49 -5
- package/assets/checks/task-new.github.mjs +33 -5
- package/assets/commands/agent-kit-digest.md +10 -5
- package/assets/commands/next-session.md +4 -4
- package/assets/commands/skill-curator.md +11 -9
- package/assets/defaults/gate-map.sh +11 -4
- package/assets/defaults/project.sh +46 -0
- package/assets/docs/GLOSSARY.md +28 -26
- package/assets/hooks/docs-guard.sh +19 -3
- package/assets/hooks/git-guard-delivery.sh +106 -13
- package/assets/hooks/proposal-guard.sh +93 -0
- package/assets/hooks/reuse-first-guard.sh +68 -14
- package/assets/hooks/skill-gate-layers.sh +1 -1
- package/assets/hooks/skill-gate.sh +26 -0
- package/assets/hooks/task-flow-guard.sh +44 -18
- package/assets/hooks/window-fill-guard.sh +1 -1
- package/assets/laws/delivery.md +13 -7
- package/assets/laws/project-documentation.md +21 -0
- package/assets/laws/verifiability.md +6 -1
- package/assets/laws/work-conduct.md +67 -3
- package/assets/patterns/git-workflow-commit.azure.md +10 -2
- package/assets/patterns/git-workflow-commit.github.md +15 -2
- package/assets/patterns/git-workflow-commit.gitlab.md +10 -2
- package/assets/patterns/git-workflow-merge.md +1 -1
- package/assets/patterns/spec-driven-domain.md +7 -1
- package/assets/patterns/spec-driven-rule.md +6 -0
- package/assets/patterns/task-flow-close.md +78 -9
- package/assets/patterns/task-flow-handoff.md +27 -4
- package/assets/patterns/task-flow-resume.md +23 -5
- package/assets/patterns/task-flow-start.md +5 -1
- package/assets/rules/browser-verification.md +10 -1
- package/assets/rules/doc-style.md +13 -5
- package/assets/rules/git-workflow.azure.md +12 -7
- package/assets/rules/git-workflow.github.md +31 -13
- package/assets/rules/git-workflow.gitlab.md +12 -7
- package/assets/rules/spec-driven.md +4 -0
- package/assets/rules/task-flow.md +47 -22
- package/assets/rules/testing.md +19 -0
- package/assets/rules/typescript-conventions.md +12 -0
- package/assets/skills/agent-kit-extend.md +24 -0
- package/assets/skills/agent-kit.md +54 -6
- package/assets/traits.json +14 -0
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +31 -16
- package/bin/agent-kit.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/lib/argv.d.ts +17 -0
- package/lib/argv.d.ts.map +1 -0
- package/lib/argv.js +44 -0
- package/lib/argv.js.map +1 -0
- package/lib/cargo.d.ts +88 -0
- package/lib/cargo.d.ts.map +1 -0
- package/lib/cargo.js +16 -0
- package/lib/cargo.js.map +1 -0
- package/lib/catalog.d.ts +18 -1
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +12 -2
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts +0 -26
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +78 -122
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +37 -0
- package/lib/companion.d.ts.map +1 -1
- package/lib/companion.js +42 -1
- package/lib/companion.js.map +1 -1
- package/lib/config.d.ts +28 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +20 -0
- package/lib/config.js.map +1 -1
- package/lib/ship.d.ts +39 -0
- package/lib/ship.d.ts.map +1 -0
- package/lib/ship.js +87 -0
- package/lib/ship.js.map +1 -0
- package/lib/shipment.d.ts +60 -0
- package/lib/shipment.d.ts.map +1 -0
- package/lib/shipment.js +247 -0
- package/lib/shipment.js.map +1 -0
- package/lib/snapshot.d.ts +30 -0
- package/lib/snapshot.d.ts.map +1 -0
- package/lib/snapshot.js +73 -0
- package/lib/snapshot.js.map +1 -0
- package/lib/traits.d.ts +32 -0
- package/lib/traits.d.ts.map +1 -0
- package/lib/traits.js +82 -0
- package/lib/traits.js.map +1 -0
- package/package.json +6 -2
- package/rt-tools-agent-kit-0.8.2.tgz +0 -0
- package/lib/submit.d.ts +0 -24
- package/lib/submit.d.ts.map +0 -1
- package/lib/submit.js +0 -26
- package/lib/submit.js.map +0 -1
- package/rt-tools-agent-kit-0.8.1.tgz +0 -0
- /package/assets/rules/{entity-conventions.md → entity-conventions.needs-admin.md} +0 -0
- /package/assets/rules/{observability.md → observability.needs-app.md} +0 -0
package/lib/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Команды и их вывод. Печать отделена от работы: команда возвращает строки и код возврата,\n * а `process.exit` зовёт только точка входа — иначе ни одну из них нельзя было бы проверить\n * спекой, не перехватывая поток вывода.\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { collectAssets, IAsset } from './assets.js';\nimport { cascadeCuts, IBrokenLink, ICascadeCut, IEntryOfCatalog, IGapOfVariant, IIdleSkip, isChosen, readCatalog } from './catalog.js';\nimport { ICompanion, isUnfilled, TCompanionState } from './companion.js';\nimport {\n CONFIG_PATH,\n DEFAULT_LAYOUT,\n IConfig,\n KINDS,\n OVERRIDES_DIR,\n PROFILE_FILE,\n readConfig,\n RT_KIT_DIR,\n SKILL_KINDS,\n TKind,\n} from './config.js';\nimport { IStaleBuild } from './freshness.js';\nimport { hooksSection, IHookBinding, SETTINGS_PATH } from './hooks-map.js';\nimport { DEFAULT_DAYS, ICount, IReadResult, ISummary, KEEP_DAYS, OBSERVATIONS_DIR, readObservations, summarize } from './observations.js';\nimport { IPlanned, isRefusal, TOutcome } from './plan.js';\nimport { ILeak, IProposal, leaksIn, markSent, marksOf, PROPOSALS_DIR, readProposals, TO_PACKAGE } from './proposals.js';\nimport { FEEDBACK_LABEL, TSubmit } from './submit.js';\nimport { ICutFound, IRetiredFound, ISyncResult, pendingOf, planSync, runSync } from './sync.js';\nimport { placeholdersOf } from './vars.js';\nimport { IAxis, IOptionOfAxis, readAxes, unansweredAxes } from './variants.js';\n\nexport interface IOutcomeOfCommand {\n readonly code: number;\n readonly lines: readonly string[];\n}\n\n/** Всё, что команда знает о мире: корень проекта, версия пакета и его каталог ресурсов. */\nexport interface IEnvironment {\n readonly root: string;\n readonly version: string;\n readonly assetsDir: string;\n /**\n * Ресурсы правлены позже, чем собран пакет, из которого идёт раскладка; `null` — сверять не с\n * чем. Считается на краю, где пакет знает своё расположение: библиотечные модули работают с\n * тем каталогом ресурсов, который им дали, и о существовании исходников не знают.\n */\n readonly stale?: IStaleBuild | null;\n /**\n * `владелец/репозиторий` пакета — куда уезжают предложения. Читается из его манифеста на\n * краю: зашитый в код адрес назвал бы чужое дерево в текстах пакета.\n */\n readonly repository?: string;\n}\n\n/** Что с файлом сделала раскладка. Прошедшее время здесь правда: `sync` уже записал. */\nconst DONE_WORD: Readonly<Record<TOutcome, string>> = {\n create: 'положен',\n update: 'переложен',\n drift: 'правлен руками',\n foreign: 'положен не пакетом',\n ok: 'без изменений',\n};\n\n/**\n * Что с файлом **сейчас**. Отдельно от прошедшего времени потому, что `doctor` и `list` ничего\n * не пишут: сказать «положен» о файле, которого в дереве нет, значит соврать читателю ровно там,\n * где он пришёл узнать состояние.\n */\nconst STATE_WORD: Readonly<Record<TOutcome, string>> = {\n create: 'нет в дереве',\n update: 'отстал от пакета',\n drift: 'правлен руками',\n foreign: 'положен не пакетом',\n ok: 'на месте',\n};\n\nconst NOT_CHOSEN: string = 'не выбран';\n/** Перечень отделяет снятое каскадом от невыбранного: дерево его не выбирало и не отвергало. */\nconst CUT_BY_CASCADE: string = 'снят каскадом';\nconst SKIPPED: string = 'пропущен';\n/** Ресурс чужого вида: в этом дереве его не существует, а не «от него отказались». */\nconst OTHER_VARIANT: string = 'другой вид';\n\nconst KIND_TITLE: Readonly<Record<TKind, string>> = {\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/** Состояние компаньона словами. У заполненного слова нет: о нём говорить нечего. */\nconst COMPANION_WORD: Readonly<Record<TCompanionState, string>> = {\n missing: 'пропал',\n draft: 'остался черновиком',\n filled: 'заполнен',\n};\n\nconst NO_CONFIG: string = `нет \\`${CONFIG_PATH}\\` — начни с \\`agent-kit init\\``;\n\n/** Куда уезжает прежнее содержимое файла, отданного пакету. */\nexport const KEPT_SUFFIX: string = '.before-rt-kit';\n\n/**\n * Имя функции профиля, которую хук ждёт. Обе формы: голая проверка наличия и спрос через\n * помощника, который о нехватке говорит вслух. Считать одну значило бы недосчитаться ровно тех\n * хуков, которые перешли на второе.\n */\nconst PROFILE_CALL: RegExp = /(?:command -v|rt_needs)[ \\t]+(rt_[a-z_]+)/g;\n\n/** Сам помощник функцией профиля не является: его везёт пакет, а не дерево. */\nconst PROFILE_HELPER: string = 'rt_needs';\n\n/**\n * Объявление функции: `rt_is_app_code() {`. Не с начала строки — хук объявляет запасной вариант\n * прямо в условии, и не считать его объявлением значило бы звать недостающим то, что у хука\n * есть.\n */\nconst PROFILE_DEFINE: RegExp = /(rt_[a-z_]+)\\s*\\(\\)\\s*\\{/g;\n\n/**\n * Функции профиля, которых ждут взятые хуки, и те из них, что дерево не определило.\n *\n * Отдельной строкой в разборе состояния потому, что на месте вызова нехватка не видна вовсе:\n * хук выходит с нулём, стоит в настройке, виден в списке — и читается как работающий. Тишина\n * при этом означает разом «нечего проверять», «проверять нечем» и «всё в порядке».\n */\nfunction profileLines(root: string, assetsDir: string, config: IConfig): string[] {\n const wanted: Set<string> = new Set();\n const defined: Set<string> = new Set();\n for (const asset of collectAssets(config, assetsDir)) {\n if (asset.kind !== 'hooks') {\n continue;\n }\n for (const found of asset.text.matchAll(PROFILE_CALL)) {\n if (found[1] !== PROFILE_HELPER) {\n wanted.add(found[1]);\n }\n }\n // Часть общих функций живёт не в профиле, а в соседнем хуке: запись наблюдения объявлена\n // в хуке наблюдений, и гарды зовут её через ту же проверку наличия. Не считать их\n // определёнными значило бы требовать от дерева переписать в профиль чужой код.\n for (const found of asset.text.matchAll(PROFILE_DEFINE)) {\n defined.add(found[1]);\n }\n }\n if (!wanted.size) {\n return [];\n }\n\n // Профиль собирается из тех же файлов, что читает сам хук: сперва разложенное умолчание\n // пакета, поверх — надстройка дерева. Судить по одной надстройке значило бы объявить мёртвым\n // каждый гард дерева, которое умолчаний не переписывало.\n const defaults: string = config.layout.defaults ?? DEFAULT_LAYOUT.defaults;\n const sources: readonly string[] = [join(root, defaults, PROFILE_FILE), join(root, RT_KIT_DIR, PROFILE_FILE)];\n for (const path of sources) {\n if (!existsSync(path)) {\n continue;\n }\n for (const found of readFileSync(path, 'utf8').matchAll(PROFILE_DEFINE)) {\n defined.add(found[1]);\n }\n }\n\n const absent: readonly string[] = [...wanted].filter((name: string): boolean => !defined.has(name)).sort();\n\n return [\n `функции профиля, которых ждут взятые хуки: ${wanted.size}`,\n ...(absent.length\n ? [\n ...absent.map((name: string): string => ` нет функции ${name} — её определяют в ${join(RT_KIT_DIR, PROFILE_FILE)}`),\n ' хук без своей функции проверку не делает и действие пропускает',\n ]\n : [' все определены']),\n ];\n}\n\nconst holes: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n [...result.missing].map(\n ([asset, names]: [string, readonly string[]]): string =>\n ` ${asset}: нет значений для ${names.map((name: string): string => `{{${name}}}`).join(', ')}`\n );\n\nconst unfilled: (result: ISyncResult) => readonly ICompanion[] = (result: ISyncResult): readonly ICompanion[] =>\n result.companions.filter(isUnfilled);\n\n/** Ось без ответа: чем её спрашивают и из чего выбирают. */\nconst axisLines: (axes: readonly IAxis[]) => string[] = (axes: readonly IAxis[]): string[] =>\n axes.flatMap((axis: IAxis): string[] => [\n ` ${axis.name} — ${axis.question}`,\n ...axis.options.map((option: IOptionOfAxis): string => ` ${option.value.padEnd(8)} ${option.title}`),\n ` выбор пишется в \\`variants\\` конфига: {\"${axis.name}\": \"${axis.options[0]?.value ?? ''}\"}`,\n ]);\n\n/**\n * Брошенное: файл лежит, а ресурс за ним больше не берут. Печатается отдельным списком и с\n * подсказкой — стереть его пакет не вправе, а промолчать не может: агент читает такой файл как\n * действующее правило.\n */\nconst abandonedLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.abandoned.length\n ? [\n `лежит от ресурсов, которые больше не берутся: ${result.abandoned.length}`,\n ...result.abandoned.map((path: string): string => ` ${path}`),\n ' их не стирает никто: рядом может лежать написанное проектом — убирать вручную',\n ]\n : [];\n\n/**\n * Ресурс, у которого нет вида под выбор дерева. Называется и то, чего не хватает, и оба способа\n * это снять: отказ без действия обходят, а не исполняют.\n */\nconst gapLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.gaps.flatMap((gap: IGapOfVariant): string[] => [\n ` ${gap.kind}/${gap.name} — есть только под ${gap.axis}: ${gap.available.join(', ')}, а выбран «${gap.chosen}»`,\n ` либо заведи вид под «${gap.chosen}», либо назови в skip: ${gap.ids.join(', ')}`,\n ]);\n\n/**\n * Гарды, которых нет в настройке агента, и готовый кусок для неё.\n *\n * Кусок печатается целиком, а не одними именами: правку в свою настройку делает проект, и\n * список «не хватает трёх» заставляет собирать JSON по памяти — там и теряется образец вызова.\n */\nconst unboundLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.unbound.length\n ? [\n `гарды разложены, но в \\`${SETTINGS_PATH}\\` их не зовёт никто: ${result.unbound.length}`,\n ...result.unbound.map(\n (binding: IHookBinding): string => ` ${binding.path} — ${binding.event}${binding.matcher ? ` ${binding.matcher}` : ''}`\n ),\n ` вставь в \\`${SETTINGS_PATH}\\` раздел \\`hooks\\` — готовый кусок ниже:`,\n ...JSON.stringify({ hooks: hooksSection(result.unbound) }, null, 4)\n .split('\\n')\n .map((line: string): string => ` ${line}`),\n ]\n : [];\n\n/**\n * Разорванные связи между ресурсами.\n *\n * Печатается предупреждением и кода возврата не меняет: дерево вправе закрыть требование своим\n * средством. Но и молчать нельзя — дерево, выбравшее паттерн без хука, которым тот живёт,\n * выглядит исправным, а расходится с пакетом на целую волну работ.\n */\nconst brokenLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.broken.length\n ? [\n `требования ресурсов, оставшиеся без ответа: ${result.broken.length}`,\n ...result.broken.map(\n (link: IBrokenLink): string => ` ${link.id} — требует ${link.requires}: ${link.unknown ? 'нет в пакете' : NOT_CHOSEN}`\n ),\n ' это предупреждение, а не отказ: требование закрывается своим средством дерева либо выбором ресурса',\n ]\n : [];\n\n/**\n * Строки отказа, которые ничего не снимают.\n *\n * Названы вместе с тем, из-за чего стали лишними: «строка ни на что не влияет» без этого читается\n * как промах в имени, и дерево идёт искать опечатку там, где её нет.\n */\nconst idleLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.idle.length\n ? [\n `строк отказа, которые ничего не снимают: ${result.idle.length}`,\n ...result.idle.map((one: IIdleSkip): string => ` ${one.id} — ${one.by ? `снято отказом от ${one.by}` : 'нет в пакете'}`),\n ' это предупреждение, а не отказ: строки убирает дерево, и раскладка идёт дальше',\n ]\n : [];\n\n/**\n * Разложенное раньше, а теперь снятое каскадом.\n *\n * Отдельно от брошенного: от брошенного дерево отказалось само и знает, где искать причину, а\n * снятое каскадом ушло вслед за родителем — в отказе его имени нет и не будет.\n */\nconst cutOnDiskLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.cutOnDisk.length\n ? [\n `лежит от ресурсов, снятых вслед за родителем: ${result.cutOnDisk.length}`,\n ...result.cutOnDisk.map(\n (one: ICutFound): string => ` ${one.path} — снят вслед за ${one.cut.parent}, отвергнут ${one.cut.root}`\n ),\n ' их не стирает никто: убирать вручную, как и брошенные',\n ]\n : [];\n\n/**\n * Названное выбором, чего дерево всё равно не получит.\n *\n * Молчать здесь нельзя вдвойне: дерево не просто осталось без ресурса — оно попросило его\n * поимённо и прочло бы отсутствие как промах раскладки.\n */\nconst namedCutLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.namedCut.length\n ? [\n `названо выбором, но не приедет: ${result.namedCut.length}`,\n ...result.namedCut.map((one: ICascadeCut): string => ` ${one.id} — снято вслед за ${one.parent}, отвергнут ${one.root}`),\n ' это предупреждение, а не отказ: возьми родителя в выбор либо убери потомка из него',\n ]\n : [];\n\n/**\n * Файлы ресурсов, ушедших из набора.\n *\n * Названы отдельно от брошенных: брошенный ресурс в наборе есть и вернётся, если дерево его\n * выберет, а снятый не вернётся никогда — и правило, по которому агент работает, у него\n * последнее.\n */\nconst retiredLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.retired.length\n ? [\n `в дереве лежат файлы ресурсов, которых в пакете больше нет: ${result.retired.length}`,\n ...result.retired.map((one: IRetiredFound): string => ` ${one.path} — снят в v${one.since}: ${one.why}`),\n ' убирает их дерево: в чужие файлы пакет не пишет',\n ]\n : [];\n\n/**\n * Предупреждения раскладки: кода возврата они не меняют и печатаются на любом её исходе.\n *\n * Иначе их не видит никто: на сошедшемся дереве проверка молчит, а удавшаяся раскладка называет\n * положенные файлы — и лишняя строка отказа, снятый каскадом файл и ушедший из набора ресурс\n * всплывали бы только там, где и без них уже красно.\n */\nconst warnings: (result: ISyncResult) => string[] = (result: ISyncResult): string[] => [\n ...brokenLines(result),\n ...idleLines(result),\n ...namedCutLines(result),\n ...retiredLines(result),\n ...cutOnDiskLines(result),\n ...abandonedLines(result),\n];\n\nconst describe: (result: ISyncResult) => string[] = (result: ISyncResult): string[] => [\n ...holes(result),\n ...gapLines(result),\n ...unboundLines(result),\n ...warnings(result),\n ...pendingOf(result).map((entry: IPlanned): string => ` ${entry.path} — ${STATE_WORD[entry.outcome]}`),\n ...unfilled(result).map((entry: ICompanion): string => ` ${entry.path} — ${COMPANION_WORD[entry.state]}`),\n];\n\n/** Имена дырок во всех ресурсах, которые дерево берёт. Без конфига — ни одной: выбор неизвестен. */\nfunction placeholdersIn(config: IConfig | null, assetsDir: string): readonly string[] {\n if (!config) {\n return [];\n }\n const names: string[] = [];\n for (const asset of collectAssets(config, assetsDir)) {\n for (const name of placeholdersOf(asset.text)) {\n if (!names.includes(name)) {\n names.push(name);\n }\n }\n }\n\n return names.sort();\n}\n\n/**\n * Что проект выбрал при заведении конфига. Пустой список — весь набор; выбор приходит сюда\n * готовым, потому что взять его негде, кроме края: у строки запуска флаг, у терминала вопрос,\n * а у неинтерактивного прогона нет ни того ни другого — и решать это команде не по чину.\n */\nexport function init(\n root: string,\n only: readonly string[] = [],\n variants: Readonly<Record<string, string>> = {},\n assetsDir: string = ''\n): IOutcomeOfCommand {\n const path: string = join(root, CONFIG_PATH);\n if (existsSync(path)) {\n return { code: 0, lines: [`${CONFIG_PATH} уже есть — оставлен как есть`] };\n }\n\n const config: object = { vars: {}, layout: DEFAULT_LAYOUT, variants, only, skip: [] };\n mkdirSync(join(root, OVERRIDES_DIR), { recursive: true });\n mkdirSync(join(root, CONFIG_PATH, '..'), { recursive: true });\n writeFileSync(path, `${JSON.stringify(config, null, 4)}\\n`, 'utf8');\n\n // Значения, которых пакет ждёт от дерева, называются здесь, а не отказом раскладки: узнать\n // о них на первом же `sync` значит начать установку с ошибки, притом что список известен\n // сразу — он вычитывается из текстов выбранных ресурсов.\n const wanted: readonly string[] = assetsDir ? placeholdersIn(readConfig(root), assetsDir) : [];\n\n return {\n code: 0,\n lines: [\n `заведён ${CONFIG_PATH}`,\n only.length ? `выбрано ресурсов: ${only.length}` : 'выбрано всё, что везёт пакет',\n ...Object.entries(variants).map(([axis, value]: [string, string]): string => `${axis}: ${value}`),\n `заведён ${OVERRIDES_DIR}/ — надстройки проекта кладутся сюда путём ресурса`,\n ...(wanted.length\n ? [\n `значения, которых ждут ресурсы, — впиши их в \\`vars\\` конфига: ${wanted.length}`,\n ...wanted.map((name: string): string => ` {{${name}}}`),\n ]\n : []),\n 'дальше: `agent-kit sync`, а своё дописывается в `.claude/rt-kit/gate-map.sh` и `project.sh`',\n ],\n };\n}\n\n/**\n * Отказ на устаревшей сборке. Раскладка из неё положила бы прежнюю редакцию ресурса и назвала\n * это сделанным: неправда дороже отказа — её замечают, когда правленое правило не действует.\n */\nconst staleRefusal: (stale: IStaleBuild) => IOutcomeOfCommand = (stale: IStaleBuild): IOutcomeOfCommand => ({\n code: 1,\n lines: [\n 'раскладка не начата: строка запуска читает собранное, а ресурсы правлены позже',\n ` правлено: ${stale.newest}`,\n ` исходные ресурсы: ${stale.source}`,\n ' собери пакет и повтори',\n ],\n});\n\nexport function sync(env: IEnvironment, check: boolean): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n if (env.stale) {\n return staleRefusal(env.stale);\n }\n\n // Ось без ответа отбивает раскладку целиком, а не пропускает свои ресурсы молча: правило\n // поставки бывает в трёх видах, и дерево, не назвавшее свой, осталось бы вовсе без правила\n // поставки — заметить это можно было бы только по тому, что гейт перестал его требовать.\n const unanswered: readonly IAxis[] = unansweredAxes(readAxes(assetsDir), config.variants);\n if (unanswered.length) {\n return { code: 1, lines: ['раскладка не начата: не выбран вид', ...axisLines(unanswered)] };\n }\n\n if (check) {\n const result: ISyncResult = planSync(config, root, version, assetsDir);\n const pending: readonly IPlanned[] = pendingOf(result);\n // Незаполненный компаньон — такое же расхождение, как отставший файл: правило разложено,\n // а имён этого дерева при нём нет, и агент читает указание, которому некуда примениться.\n const empty: readonly ICompanion[] = unfilled(result);\n // Гард, которого не зовёт настройка агента, — такое же расхождение, как отставший файл:\n // он разложен, он коммитится, и по дереву его не отличить от работающего.\n // Разорванная связь в счёт расхождений не идёт: дерево вправе закрыть требование своим\n // средством, и отказ отбивал бы законную раскладку. Но и сходство её не отменяет —\n // предупреждение печатается и там, где расходиться больше нечему.\n const count: number = result.missing.size + result.gaps.length + pending.length + empty.length + result.unbound.length;\n if (!count) {\n return { code: 0, lines: [`sync --check: разложенное сходится с пакетом v${version}`, ...warnings(result)] };\n }\n\n return { code: 1, lines: [`sync --check: расхождений ${count}`, ...describe(result)] };\n }\n\n const result: ISyncResult = runSync(config, root, version, assetsDir);\n // Перечисляются только дырки: раскладка не начата, и назвать файл «положенным» значило бы\n // сказать неправду — на диске его нет.\n if (result.missing.size) {\n return { code: 1, lines: ['раскладка не начата: нечего подставить в дырки', ...holes(result)] };\n }\n\n // Ресурс без вида под выбор дерева отбивает раскладку целиком, а не выпадает из неё молча:\n // правило, разложенное без инструмента, который оно зовёт, читается как действующее.\n if (result.gaps.length) {\n return {\n code: 1,\n lines: ['раскладка не начата: у этих ресурсов нет вида под выбор дерева', ...gapLines(result)],\n };\n }\n\n const refused: readonly IPlanned[] = result.planned.filter((entry: IPlanned): boolean => isRefusal(entry.outcome));\n if (refused.length) {\n return {\n code: 1,\n lines: [\n 'раскладка не начата: эти файлы пакет переписывать не станет',\n ...refused.map((entry: IPlanned): string => ` ${entry.path} — ${DONE_WORD[entry.outcome]}`),\n 'правку надо либо перенести в надстройку, либо снять — и повторить',\n `положенное не пакетом отдаётся ему командой \\`agent-kit adopt\\`: прежнее содержимое ляжет рядом с пометкой \\`${KEPT_SUFFIX}\\``,\n ],\n };\n }\n\n // Раскладка удалась, а гарды могут остаться неподключёнными: настройка агента принадлежит\n // дереву, и пакет в неё не пишет. Код возврата остаётся нулевым — файлы легли, — но молчать\n // об этом нельзя: узнают иначе, когда что-нибудь пройдёт мимо гарда.\n return {\n code: 0,\n lines: [\n ...(result.written.length\n ? [`разложено файлов: ${result.written.length}`, ...result.written.map((path: string): string => ` ${path}`)]\n : ['всё уже разложено']),\n ...unboundLines(result),\n ...warnings(result),\n ],\n };\n}\n\n/**\n * Отдать пакету файл, который лежит в дереве не от него.\n *\n * Пока команды не было, `sync` отказывал на такой файл поимённо и предлагал «перенести правку в\n * надстройку или снять» — то есть работу, которую делают руками, и до неё же сводилась вся\n * установка в живое дерево. При этом один чужой файл останавливал раскладку целиком.\n *\n * Молчаливой перезаписи здесь нет и быть не может: в файле лежит то, чего в дереве больше нигде\n * нет. Поэтому переход — это переименование прежнего содержимого рядом и повторный `sync`:\n * пакет кладёт своё, а прежнее остаётся на диске под именем с пометкой и ждёт разбора.\n */\nexport function adopt(env: IEnvironment, names: readonly string[]): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n const foreign: readonly IPlanned[] = planSync(config, root, version, assetsDir).planned.filter(\n (entry: IPlanned): boolean => entry.outcome === 'foreign'\n );\n if (!foreign.length) {\n return { code: 0, lines: ['чужих файлов на путях пакета нет'] };\n }\n\n // Имена принимаются как их печатает `sync`: путём в дереве. Без имён отдаются все — на\n // свежей установке их бывает столько же, сколько ресурсов, и перечислять их руками значит\n // делать ту же работу, ради которой команда заведена.\n const wanted: readonly IPlanned[] = names.length\n ? foreign.filter((entry: IPlanned): boolean => names.some((name: string): boolean => entry.path.endsWith(name)))\n : foreign;\n if (!wanted.length) {\n return {\n code: 1,\n lines: ['ни одно имя не отвечает чужому файлу; чужие сейчас такие:', ...foreign.map((e: IPlanned): string => ` ${e.path}`)],\n };\n }\n\n const moved: string[] = [];\n const blocked: string[] = [];\n for (const entry of wanted) {\n const path: string = join(root, entry.path);\n const kept: string = `${path}${KEPT_SUFFIX}`;\n if (existsSync(kept)) {\n blocked.push(` ${entry.path}${KEPT_SUFFIX} — уже лежит, разбери его прежде`);\n continue;\n }\n renameSync(path, kept);\n moved.push(` ${entry.path} → ${entry.path}${KEPT_SUFFIX}`);\n }\n\n return {\n code: blocked.length ? 1 : 0,\n lines: [\n ...(moved.length ? [`прежнее содержимое отложено: ${moved.length}`, ...moved, 'дальше: `agent-kit sync`'] : []),\n ...(blocked.length ? ['не тронуто:', ...blocked] : []),\n ],\n };\n}\n\n/**\n * Сколько незагруженных правил называется поимённо. На коротком отрезке их бывает больше\n * тридцати, и список во весь экран прячет всё остальное, ради чего сводку и открыли.\n */\nconst UNUSED_SHOWN: number = 12;\n\n/** Чем сводка отвечает: отрезок в днях, сегодняшний день и вид вывода. */\nexport interface IStatsOptions {\n readonly days: number;\n /** Сегодняшний день, `ГГГГ-ММ-ДД`. Приходит с края: команду со своими часами не проверить. */\n readonly today: string;\n readonly json: boolean;\n}\n\n/** Столбиком: имя и счёт. Ширина по самому длинному имени — иначе счёт читается по одному. */\nconst countLines: (counted: readonly ICount[]) => string[] = (counted: readonly ICount[]): string[] => {\n const width: number = counted.reduce((found: number, entry: ICount): number => Math.max(found, entry.name.length), 0);\n\n return counted.map((entry: ICount): string => ` ${entry.name.padEnd(width)} ${entry.count}`);\n};\n\n/** Имена скилов, разложенных в это дерево: правила, паттерны и скилы без закона. */\nconst skillsOf: (config: IConfig, assetsDir: string) => readonly string[] = (config: IConfig, assetsDir: string): readonly string[] =>\n collectAssets(config, assetsDir)\n .filter((asset: IAsset): boolean => SKILL_KINDS.includes(asset.kind))\n .map((asset: IAsset): string => asset.name);\n\n/**\n * Сводка наблюдений за отрезок дней.\n *\n * Отдельная строка про незагруженное — то, ради чего сводка вообще нужна: чем пользуются, видно\n * и по работе, а вот правило, которое не открыли ни разу, ничем себя не выдаёт. Сокращать текст\n * правил так же ценно, как дополнять.\n */\nexport function stats(env: IEnvironment, options: IStatsOptions): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n // Выключенная запись — не пустая сводка: нули на месте наблюдений читаются как «ничего не\n // делали», тогда как на самом деле никто и не смотрел.\n if (!config.observe) {\n return {\n code: 0,\n lines: [\n 'запись наблюдений выключена ключом `observe` в конфиге',\n `включить — убрать ключ или поставить \\`\"observe\": true\\`; пишутся они в ${OBSERVATIONS_DIR}/`,\n ],\n };\n }\n\n const days: number = options.days > 0 ? options.days : DEFAULT_DAYS;\n const result: IReadResult = readObservations(root, options.today, days);\n const summary: ISummary = summarize(result.observations, skillsOf(config, assetsDir), days);\n\n if (options.json) {\n return { code: 0, lines: [JSON.stringify({ ...summary, swept: result.swept })] };\n }\n\n if (result.silent) {\n return {\n code: 0,\n lines: [\n 'наблюдений нет: записи не велось ни разу',\n `их пишут гарды в ${OBSERVATIONS_DIR}/ — проверь, что гарды разложены и подключены в ${SETTINGS_PATH}`,\n ],\n };\n }\n\n if (!summary.total) {\n return {\n code: 0,\n lines: [\n `наблюдений за ${days} дн. нет ни одного, а записи велись раньше`,\n ...(result.swept.length ? [`снято по сроку хранения (${KEEP_DAYS} дн.): ${result.swept.length}`] : []),\n 'возьми отрезок длиннее: `--days 14`',\n ],\n };\n }\n\n return {\n code: 0,\n lines: [\n `наблюдения за ${days} дн., заходов ${summary.sessions}, событий ${summary.total}`,\n ...(summary.versions.length ? [`версии пакета в записях: ${summary.versions.join(', ')}`] : []),\n '',\n `правил загружено: ${summary.loads.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.loads),\n ...(summary.unused.length\n ? [\n '',\n `разложено и не загружено ни разу: ${summary.unused.length} из ${skillsOf(config, assetsDir).length}`,\n ...summary.unused.slice(0, UNUSED_SHOWN).map((name: string): string => ` ${name}`),\n // Список говорится не весь, и об этом говорится вслух: молчаливый обрыв\n // читается как «вот они все», и правило, не попавшее в первую дюжину,\n // считалось бы работающим.\n ...(summary.unused.length > UNUSED_SHOWN\n ? [` … и ещё ${summary.unused.length - UNUSED_SHOWN} — целиком в \\`--json\\``]\n : []),\n ]\n : []),\n ...(summary.denials.length\n ? [\n '',\n `гейт отбивал: ${summary.denials.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.denials),\n ...(summary.kinds.length\n ? [' чаще всего на:', ...countLines(summary.kinds).map((line: string): string => ` ${line}`)]\n : []),\n ]\n : []),\n ...(summary.guards.length\n ? [\n '',\n `гарды отказывали: ${summary.guards.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.guards),\n ]\n : []),\n ...(result.swept.length ? ['', `снято по сроку хранения (${KEEP_DAYS} дн.): ${result.swept.length}`] : []),\n '',\n `пакет v${version}`,\n ],\n };\n}\n\n/** Чем отправка живёт: чем заводить запись, куда и чем себя выдаёт это дерево. */\nexport interface IProposeOptions {\n /** Печатать, что уехало бы, и ничего не отправлять. */\n readonly dryRun: boolean;\n readonly submit: TSubmit;\n /** `владелец/репозиторий` пакета — из его манифеста, а не из кода. */\n readonly repository: string;\n /** Адрес удалённого репозитория этого дерева: он тоже называет дерево. */\n readonly remote: string;\n /** Сводка наблюдений, которая едет вместе с предложением: без цифр это мнение. */\n readonly summary: readonly string[];\n}\n\n/** Тело записи: место, повод, готовый текст — и сводка под ними. */\nconst issueBody: (proposal: IProposal, summary: readonly string[], version: string) => string = (\n proposal: IProposal,\n summary: readonly string[],\n version: string\n): string =>\n [\n `Ресурс: \\`${proposal.resource}\\``,\n `Пакет: v${version}`,\n '',\n proposal.body,\n '',\n '## Наблюдения дерева, из которого пришло предложение',\n '',\n '```',\n ...summary,\n '```',\n '',\n 'Заведено `agent-kit propose`. Дерево, из которого оно пришло, здесь не называется намеренно.',\n ].join('\\n');\n\n/**\n * Отправка предложений, адресованных пакету.\n *\n * Наружу уезжает только адрес «пакет»: «компаньон» и «дерево» — про имена и надстройки этого\n * дерева, и в репозитории пакета им делать нечего. Перед отправкой текст сверяется на адрес\n * дерева: файл уезжает в чужой репозиторий целиком, и проверка здесь дешевле, чем разбор потом.\n */\nexport function propose(env: IEnvironment, options: IProposeOptions): IOutcomeOfCommand {\n const { root, version } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n if (!options.repository) {\n return { code: 1, lines: ['куда отправлять — неизвестно: в манифесте пакета нет адреса репозитория'] };\n }\n\n const all: readonly IProposal[] = readProposals(root);\n const mine: readonly IProposal[] = all.filter((entry: IProposal): boolean => entry.address === TO_PACKAGE && !entry.sent);\n if (!mine.length) {\n const others: number = all.filter((entry: IProposal): boolean => entry.address !== TO_PACKAGE).length;\n const sent: number = all.filter((entry: IProposal): boolean => Boolean(entry.sent)).length;\n\n return {\n code: 0,\n lines: [\n 'отправлять нечего: предложений с адресом «пакет» и без пометки об отправке нет',\n ...(others ? [`с другими адресами: ${others} — они правятся здесь же, надстройкой и компаньоном`] : []),\n ...(sent ? [`уже отправлено: ${sent}`] : []),\n ...(all.length ? [] : [`предложения кладутся в ${PROPOSALS_DIR}/ — форма в шаблоне \\`proposal.md\\``]),\n ],\n };\n }\n\n // Утечка отбивает отправку целиком, а не свой блок: файл разбирает человек, и «уехало два из\n // трёх» он прочтёт как «всё в порядке».\n const marks: readonly string[] = marksOf(root, options.remote);\n const leaked: readonly { proposal: IProposal; leak: ILeak }[] = mine.flatMap(\n (proposal: IProposal): { proposal: IProposal; leak: ILeak }[] =>\n leaksIn(proposal.body, marks).map((leak: ILeak): { proposal: IProposal; leak: ILeak } => ({ proposal, leak }))\n );\n if (leaked.length) {\n return {\n code: 1,\n lines: [\n `отправка не начата: в тексте предложений назван адрес этого дерева — ${leaked.length}`,\n ...leaked.map(\n ({ proposal, leak }: { proposal: IProposal; leak: ILeak }): string =>\n ` ${proposal.file}:${proposal.line + leak.line} — ${leak.why}\\n ${leak.text}`\n ),\n 'предложение уезжает в чужой репозиторий целиком: правь текст, а не обходи проверку',\n ],\n };\n }\n\n if (options.dryRun) {\n return {\n code: 0,\n lines: [\n `уехало бы записей: ${mine.length} → ${options.repository}, метка ${FEEDBACK_LABEL}`,\n ...mine.map((entry: IProposal): string => ` ${entry.resource} (${entry.file}:${entry.line})`),\n 'сводка наблюдений едет вместе с ними',\n ],\n };\n }\n\n const done: string[] = [];\n for (const proposal of mine) {\n let url: string = '';\n try {\n url = options.submit({\n repository: options.repository,\n title: `предложение: ${proposal.resource}`,\n body: issueBody(proposal, options.summary, version),\n label: FEEDBACK_LABEL,\n });\n } catch (error: unknown) {\n return {\n code: 1,\n lines: [\n ...(done.length ? [`отправлено до отказа: ${done.length}`, ...done] : []),\n `отправка оборвалась на ${proposal.resource}: ${(error as Error).message.split('\\n')[0]}`,\n // Три причины покрывают почти все отказы, и ни одну из них не видно из\n // сообщения помощника: он говорит про метку, доступ и сам себя одинаково глухо.\n `проверь: помощник хостинга стоит и вошёл в учётную запись; в ${options.repository} заведена метка ${FEEDBACK_LABEL}; у учётной записи есть право заводить записи`,\n 'файл предложений остался на месте — отправленное помечено, остальное уедет повторным запуском',\n ],\n };\n }\n\n // Пометка ложится сразу, а не после всех: оборвавшаяся отправка иначе увозит половину\n // предложений и не оставляет следа, по которому видно, какую именно.\n const path: string = join(root, proposal.file);\n writeFileSync(path, markSent(readFileSync(path, 'utf8'), proposal, url), 'utf8');\n done.push(` ${proposal.resource} → ${url}`);\n }\n\n return {\n code: 0,\n lines: [\n `заведено записей: ${done.length} в ${options.repository}`,\n ...done,\n 'разбирается сведением: `/agent-kit-digest` в репозитории пакета — оно и заводит задачу',\n ],\n };\n}\n\nexport function doctor(env: IEnvironment): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n const result: ISyncResult = planSync(config, root, version, assetsDir);\n const counted: Map<TOutcome, number> = new Map();\n for (const entry of result.planned) {\n counted.set(entry.outcome, (counted.get(entry.outcome) ?? 0) + 1);\n }\n\n const catalog: readonly IEntryOfCatalog[] = readCatalog(assetsDir);\n const taken: number = collectAssets(config, assetsDir).length;\n const unanswered: readonly IAxis[] = unansweredAxes(readAxes(assetsDir), config.variants);\n const chosen: string[] = Object.entries(config.variants).map(([axis, value]: [string, string]): string => `${axis}: ${value}`);\n // Ресурс чужого вида в «не выбрано» не идёт: проект от него не отказывался — его в этом\n // дереве не существует, как не существует второго правила поставки.\n const foreignVariant: readonly IEntryOfCatalog[] = catalog.filter(\n (entry: IEntryOfCatalog): boolean => entry.variant !== null && config.variants[entry.variant.axis] !== entry.variant.value\n );\n const other: number = foreignVariant.length;\n // Ресурс, названный и в отказе, и чужим видом, считается один раз — иначе «не выбрано»\n // уходит в минус, а минус в отчёте читается как поломка счёта, а не как двойной счёт.\n const skipped: number = config.skip.filter((id: string): boolean =>\n foreignVariant.every((entry: IEntryOfCatalog): boolean => entry.id !== id)\n ).length;\n\n // Снятое каскадом считается и называется отдельно от невыбранного: дерево его не выбирало и\n // не отвергало — оно ушло вслед за родителем, и искать его в отказе читатель пойдёт зря.\n const cuts: readonly ICascadeCut[] = cascadeCuts(catalog, config);\n const cut: ReadonlySet<string> = new Set(cuts.map((one: ICascadeCut): string => one.id));\n\n // Невыбранное называется поимённо: число «не выбрано: 73» не отвечает ни на один вопрос,\n // ради которого его читают, — ни какого ресурса не хватает, ни требуется ли он соседу.\n const unchosen: readonly IEntryOfCatalog[] = catalog.filter(\n (entry: IEntryOfCatalog): boolean =>\n !isChosen(entry, config) &&\n !config.skip.includes(entry.id) &&\n foreignVariant.every((one: IEntryOfCatalog): boolean => one.id !== entry.id)\n );\n\n const lines: string[] = [\n `пакет v${version}, везёт ресурсов ${catalog.length}, взято ${taken}`,\n `не выбрано: ${catalog.length - taken - skipped - other - cut.size}, пропущено: ${skipped}, другой вид: ${other}, снято каскадом: ${cut.size}`,\n ...unchosen.map((entry: IEntryOfCatalog): string => ` не выбран: ${entry.id}`),\n ...cuts.map(\n (one: ICascadeCut): string =>\n ` снят каскадом: ${one.id} — вслед за ${one.parent}${one.parent === one.root ? '' : `, отвергнут ${one.root}`}`\n ),\n ...profileLines(root, assetsDir, config),\n `значений в конфиге: ${Object.keys(config.vars).length}`,\n ...chosen,\n ...[...counted].map(([outcome, count]: [TOutcome, number]): string => `${STATE_WORD[outcome]}: ${count}`),\n ...describe(result),\n ...(unanswered.length ? ['не выбран вид — раскладка не начнётся:', ...axisLines(unanswered)] : []),\n // Про устаревшую сборку `doctor` говорит, но отказом её не считает: он ничего не пишет,\n // и прочитать состояние дерева можно и из вчерашней сборки — знать бы, что она вчерашняя.\n ...(env.stale ? ['собранное отстало от исходников — раскладка откажет:', ` правлено: ${env.stale.newest}`] : []),\n ];\n\n return { code: 0, lines };\n}\n\n/**\n * Что пакет везёт и что из этого взято здесь.\n *\n * Работает и без конфига: посмотреть, из чего выбирать, нужно раньше, чем выбор сделан, — иначе\n * имена законов взять неоткуда, кроме исходников пакета.\n */\nexport function list(env: IEnvironment): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n const catalog: readonly IEntryOfCatalog[] = readCatalog(assetsDir);\n const planned: Map<string, TOutcome> = new Map();\n const cutByCascade: ReadonlySet<string> = new Set(config ? cascadeCuts(catalog, config).map((one: ICascadeCut): string => one.id) : []);\n\n if (config) {\n for (const entry of planSync(config, root, version, assetsDir).planned) {\n planned.set(entry.asset, entry.outcome);\n }\n }\n\n const stateOf: (entry: IEntryOfCatalog) => string = (entry: IEntryOfCatalog): string => {\n if (!config) {\n return 'везёт пакет';\n }\n if (entry.variant && config.variants[entry.variant.axis] !== entry.variant.value) {\n return OTHER_VARIANT;\n }\n if (config.skip.includes(entry.id)) {\n return SKIPPED;\n }\n if (!isChosen(entry, config)) {\n return NOT_CHOSEN;\n }\n if (cutByCascade.has(entry.id)) {\n return CUT_BY_CASCADE;\n }\n const outcome: TOutcome | undefined = planned.get(entry.id);\n\n // Ресурса нет среди запланированных ровно в одном случае: в нём осталась дырка без\n // значения, и до решения о судьбе файла раскладка не дошла.\n return outcome ? STATE_WORD[outcome] : 'дырка без значения';\n };\n\n const name: number = catalog.reduce((found: number, entry: IEntryOfCatalog): number => Math.max(found, entry.name.length), 0);\n const state: number = catalog.reduce((found: number, entry: IEntryOfCatalog): number => Math.max(found, stateOf(entry).length), 0);\n const lines: string[] = [config ? `пакет v${version}` : `пакет v${version}, ${CONFIG_PATH} ещё не заведён`];\n\n for (const kind of KINDS) {\n const entries: readonly IEntryOfCatalog[] = catalog.filter((entry: IEntryOfCatalog): boolean => entry.kind === kind);\n if (!entries.length) {\n continue;\n }\n lines.push('', KIND_TITLE[kind]);\n lines.push(\n ...entries.map(\n (entry: IEntryOfCatalog): string => ` ${entry.name.padEnd(name)} ${stateOf(entry).padEnd(state)} ${entry.title}`\n )\n );\n }\n\n return { code: 0, lines };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Команды и их вывод. Печать отделена от работы: команда возвращает строки и код возврата,\n * а `process.exit` зовёт только точка входа — иначе ни одну из них нельзя было бы проверить\n * спекой, не перехватывая поток вывода.\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { collectAssets } from './assets.js';\nimport { cascadeCuts, IBrokenLink, ICascadeCut, IEntryOfCatalog, IGapOfVariant, IIdleSkip, isChosen, readCatalog } from './catalog.js';\nimport { debtLine, ICompanion, isUnfilled, IUnaddressed, pathOf as companionPathOf, TCompanionState, unaddressedOf } from './companion.js';\nimport { CONFIG_PATH, DEFAULT_LAYOUT, IConfig, KINDS, OVERRIDES_DIR, PROFILE_FILE, readConfig, RT_KIT_DIR, TKind } from './config.js';\nimport { IStaleBuild } from './freshness.js';\nimport { hooksSection, IHookBinding, SETTINGS_PATH } from './hooks-map.js';\nimport { DEFAULT_DAYS, ICount, IReadResult, ISummary, KEEP_DAYS, OBSERVATIONS_DIR, readObservations, summarize } from './observations.js';\nimport { IPlanned, isRefusal, TOutcome } from './plan.js';\nimport { laidOutSkills } from './snapshot.js';\nimport { ICutFound, IRetiredFound, ISyncResult, pendingOf, planSync, runSync } from './sync.js';\nimport { answersRequirement, ITrait, readTraits, unknownTraits } from './traits.js';\nimport { placeholdersOf } from './vars.js';\nimport { IAxis, IOptionOfAxis, readAxes, unansweredAxes } from './variants.js';\n\nexport interface IOutcomeOfCommand {\n readonly code: number;\n readonly lines: readonly string[];\n}\n\n/** Всё, что команда знает о мире: корень проекта, версия пакета и его каталог ресурсов. */\nexport interface IEnvironment {\n readonly root: string;\n readonly version: string;\n readonly assetsDir: string;\n /**\n * Ресурсы правлены позже, чем собран пакет, из которого идёт раскладка; `null` — сверять не с\n * чем. Считается на краю, где пакет знает своё расположение: библиотечные модули работают с\n * тем каталогом ресурсов, который им дали, и о существовании исходников не знают.\n */\n readonly stale?: IStaleBuild | null;\n}\n\n/** Что с файлом сделала раскладка. Прошедшее время здесь правда: `sync` уже записал. */\nconst DONE_WORD: Readonly<Record<TOutcome, string>> = {\n create: 'положен',\n update: 'переложен',\n drift: 'правлен руками',\n foreign: 'положен не пакетом',\n ok: 'без изменений',\n};\n\n/**\n * Что с файлом **сейчас**. Отдельно от прошедшего времени потому, что `doctor` и `list` ничего\n * не пишут: сказать «положен» о файле, которого в дереве нет, значит соврать читателю ровно там,\n * где он пришёл узнать состояние.\n */\nconst STATE_WORD: Readonly<Record<TOutcome, string>> = {\n create: 'нет в дереве',\n update: 'отстал от пакета',\n drift: 'правлен руками',\n foreign: 'положен не пакетом',\n ok: 'на месте',\n};\n\nconst NOT_CHOSEN: string = 'не выбран';\n/** Перечень отделяет снятое каскадом от невыбранного: дерево его не выбирало и не отвергало. */\nconst CUT_BY_CASCADE: string = 'снят каскадом';\nconst SKIPPED: string = 'пропущен';\n/** Ресурс чужого вида: в этом дереве его не существует, а не «от него отказались». */\nconst OTHER_VARIANT: string = 'другой вид';\n/** Ресурс, которому нужно свойство дерева: дерево его не отвергало — свойства у него нет. */\nconst NEEDS_TRAIT: string = 'нужно свойство';\n\nconst KIND_TITLE: Readonly<Record<TKind, string>> = {\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/** Состояние компаньона словами. У заполненного слова нет: о нём говорить нечего. */\nconst COMPANION_WORD: Readonly<Record<TCompanionState, string>> = {\n missing: 'пропал',\n draft: 'остался черновиком',\n filled: 'заполнен',\n};\n\nconst NO_CONFIG: string = `нет \\`${CONFIG_PATH}\\` — начни с \\`agent-kit init\\``;\n\n/** Куда уезжает прежнее содержимое файла, отданного пакету. */\nexport const KEPT_SUFFIX: string = '.before-rt-kit';\n\n/**\n * Имя функции профиля, которую хук ждёт. Обе формы: голая проверка наличия и спрос через\n * помощника, который о нехватке говорит вслух. Считать одну значило бы недосчитаться ровно тех\n * хуков, которые перешли на второе.\n */\nconst PROFILE_CALL: RegExp = /(?:command -v|rt_needs)[ \\t]+(rt_[a-z_]+)/g;\n\n/** Сам помощник функцией профиля не является: его везёт пакет, а не дерево. */\nconst PROFILE_HELPER: string = 'rt_needs';\n\n/**\n * Объявление функции: `rt_is_app_code() {`. Не с начала строки — хук объявляет запасной вариант\n * прямо в условии, и не считать его объявлением значило бы звать недостающим то, что у хука\n * есть.\n */\nconst PROFILE_DEFINE: RegExp = /(rt_[a-z_]+)\\s*\\(\\)\\s*\\{/g;\n\n/**\n * Функции профиля, которых ждут взятые хуки, и те из них, что дерево не определило.\n *\n * Отдельной строкой в разборе состояния потому, что на месте вызова нехватка не видна вовсе:\n * хук выходит с нулём, стоит в настройке, виден в списке — и читается как работающий. Тишина\n * при этом означает разом «нечего проверять», «проверять нечем» и «всё в порядке».\n */\nfunction profileLines(root: string, assetsDir: string, config: IConfig): string[] {\n const wanted: Set<string> = new Set();\n const defined: Set<string> = new Set();\n for (const asset of collectAssets(config, assetsDir)) {\n if (asset.kind !== 'hooks') {\n continue;\n }\n for (const found of asset.text.matchAll(PROFILE_CALL)) {\n if (found[1] !== PROFILE_HELPER) {\n wanted.add(found[1]);\n }\n }\n // Часть общих функций живёт не в профиле, а в соседнем хуке: запись наблюдения объявлена\n // в хуке наблюдений, и гарды зовут её через ту же проверку наличия. Не считать их\n // определёнными значило бы требовать от дерева переписать в профиль чужой код.\n for (const found of asset.text.matchAll(PROFILE_DEFINE)) {\n defined.add(found[1]);\n }\n }\n if (!wanted.size) {\n return [];\n }\n\n // Профиль собирается из тех же файлов, что читает сам хук: сперва разложенное умолчание\n // пакета, поверх — надстройка дерева. Судить по одной надстройке значило бы объявить мёртвым\n // каждый гард дерева, которое умолчаний не переписывало.\n const defaults: string = config.layout.defaults ?? DEFAULT_LAYOUT.defaults;\n const sources: readonly string[] = [join(root, defaults, PROFILE_FILE), join(root, RT_KIT_DIR, PROFILE_FILE)];\n for (const path of sources) {\n if (!existsSync(path)) {\n continue;\n }\n for (const found of readFileSync(path, 'utf8').matchAll(PROFILE_DEFINE)) {\n defined.add(found[1]);\n }\n }\n\n const absent: readonly string[] = [...wanted].filter((name: string): boolean => !defined.has(name)).sort();\n\n return [\n `функции профиля, которых ждут взятые хуки: ${wanted.size}`,\n ...(absent.length\n ? [\n ...absent.map((name: string): string => ` нет функции ${name} — её определяют в ${join(RT_KIT_DIR, PROFILE_FILE)}`),\n ' хук без своей функции проверку не делает и действие пропускает',\n ]\n : [' все определены']),\n ];\n}\n\nconst holes: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n [...result.missing].map(\n ([asset, names]: [string, readonly string[]]): string =>\n ` ${asset}: нет значений для ${names.map((name: string): string => `{{${name}}}`).join(', ')}`\n );\n\nconst unfilled: (result: ISyncResult) => readonly ICompanion[] = (result: ISyncResult): readonly ICompanion[] =>\n result.companions.filter(isUnfilled);\n\n/**\n * Строка про компаньон, которому нечего сказать.\n *\n * У правила, требующего свойства, которого дерево не назвало, это не черновик, а лишний файл:\n * заполнять его нечем — ни одной статье такого правила здесь не отвечает ни файл, ни символ.\n * Такое правило доезжает сюда только выбором поимённо, и верное действие тут обратное\n * заполнению — снять ресурс строкой отказа.\n */\nconst companionLine: (entry: ICompanion) => string = (entry: ICompanion): string =>\n entry.needs === null\n ? ` ${entry.path} — ${COMPANION_WORD[entry.state]}`\n : ` ${entry.path} — правилу нужно свойство «${entry.needs}»: заполнять нечем, снимай ресурс строкой в \\`skip\\``;\n\n/** Ось без ответа: чем её спрашивают и из чего выбирают. */\nconst axisLines: (axes: readonly IAxis[]) => string[] = (axes: readonly IAxis[]): string[] =>\n axes.flatMap((axis: IAxis): string[] => [\n ` ${axis.name} — ${axis.question}`,\n ...axis.options.map((option: IOptionOfAxis): string => ` ${option.value.padEnd(8)} ${option.title}`),\n ` выбор пишется в \\`variants\\` конфига: {\"${axis.name}\": \"${axis.options[0]?.value ?? ''}\"}`,\n ]);\n\n/**\n * Брошенное: файл лежит, а ресурс за ним больше не берут. Печатается отдельным списком и с\n * подсказкой — стереть его пакет не вправе, а промолчать не может: агент читает такой файл как\n * действующее правило.\n */\nconst abandonedLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.abandoned.length\n ? [\n `лежит от ресурсов, которые больше не берутся: ${result.abandoned.length}`,\n ...result.abandoned.map((path: string): string => ` ${path}`),\n ' их не стирает никто: рядом может лежать написанное проектом — убирать вручную',\n ]\n : [];\n\n/**\n * Ресурс, у которого нет вида под выбор дерева. Называется и то, чего не хватает, и оба способа\n * это снять: отказ без действия обходят, а не исполняют.\n */\nconst gapLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.gaps.flatMap((gap: IGapOfVariant): string[] => [\n ` ${gap.kind}/${gap.name} — есть только под ${gap.axis}: ${gap.available.join(', ')}, а выбран «${gap.chosen}»`,\n ` либо заведи вид под «${gap.chosen}», либо назови в skip: ${gap.ids.join(', ')}`,\n ]);\n\n/**\n * Свойства, названные не по перечню пакета, — и деревом, и ресурсами.\n *\n * Обе стороны собираются одной функцией, потому что промах у них общий: имя свойства написано\n * так, как его никто не объявлял. Разница только в том, где оно написано, и потому в строке\n * отказа стоит место, а не одно имя.\n */\nfunction strangeTraits(config: IConfig, assetsDir: string): readonly string[] {\n const traits: readonly ITrait[] = readTraits(assetsDir);\n const lines: string[] = unknownTraits(config.has, traits).map(\n (trait: string): string => ` \\`${trait}\\` — названо деревом в \\`has\\`, а пакет такого свойства не объявлял`\n );\n\n for (const entry of readCatalog(assetsDir)) {\n if (entry.needs !== null && unknownTraits([entry.needs], traits).length) {\n lines.push(` \\`${entry.needs}\\` — требует ${entry.id}, а пакет такого свойства не объявлял`);\n }\n }\n\n return lines.length ? [...lines, ` объявленные свойства: ${traits.map((trait: ITrait): string => trait.value).join(', ')}`] : [];\n}\n\n/**\n * Гарды, которых нет в настройке агента, и готовый кусок для неё.\n *\n * Кусок печатается целиком, а не одними именами: правку в свою настройку делает проект, и\n * список «не хватает трёх» заставляет собирать JSON по памяти — там и теряется образец вызова.\n */\nconst unboundLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.unbound.length\n ? [\n `гарды разложены, но в \\`${SETTINGS_PATH}\\` их не зовёт никто: ${result.unbound.length}`,\n ...result.unbound.map(\n (binding: IHookBinding): string => ` ${binding.path} — ${binding.event}${binding.matcher ? ` ${binding.matcher}` : ''}`\n ),\n ` вставь в \\`${SETTINGS_PATH}\\` раздел \\`hooks\\` — готовый кусок ниже:`,\n ...JSON.stringify({ hooks: hooksSection(result.unbound) }, null, 4)\n .split('\\n')\n .map((line: string): string => ` ${line}`),\n ]\n : [];\n\n/**\n * Разорванные связи между ресурсами.\n *\n * Печатается предупреждением и кода возврата не меняет: дерево вправе закрыть требование своим\n * средством. Но и молчать нельзя — дерево, выбравшее паттерн без хука, которым тот живёт,\n * выглядит исправным, а расходится с пакетом на целую волну работ.\n */\nconst brokenLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.broken.length\n ? [\n `требования ресурсов, оставшиеся без ответа: ${result.broken.length}`,\n ...result.broken.map(\n (link: IBrokenLink): string => ` ${link.id} — требует ${link.requires}: ${link.unknown ? 'нет в пакете' : NOT_CHOSEN}`\n ),\n ' это предупреждение, а не отказ: требование закрывается своим средством дерева либо выбором ресурса',\n ]\n : [];\n\n/**\n * Строки отказа, которые ничего не снимают.\n *\n * Названы вместе с тем, из-за чего стали лишними: «строка ни на что не влияет» без этого читается\n * как промах в имени, и дерево идёт искать опечатку там, где её нет.\n */\nconst idleLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.idle.length\n ? [\n `строк отказа, которые ничего не снимают: ${result.idle.length}`,\n ...result.idle.map((one: IIdleSkip): string => ` ${one.id} — ${one.by ? `снято отказом от ${one.by}` : 'нет в пакете'}`),\n ' это предупреждение, а не отказ: строки убирает дерево, и раскладка идёт дальше',\n ]\n : [];\n\n/**\n * Разложенное раньше, а теперь снятое каскадом.\n *\n * Отдельно от брошенного: от брошенного дерево отказалось само и знает, где искать причину, а\n * снятое каскадом ушло вслед за родителем — в отказе его имени нет и не будет.\n */\nconst cutOnDiskLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.cutOnDisk.length\n ? [\n `лежит от ресурсов, снятых вслед за родителем: ${result.cutOnDisk.length}`,\n ...result.cutOnDisk.map(\n (one: ICutFound): string => ` ${one.path} — снят вслед за ${one.cut.parent}, отвергнут ${one.cut.root}`\n ),\n ' их не стирает никто: убирать вручную, как и брошенные',\n ]\n : [];\n\n/**\n * Названное выбором, чего дерево всё равно не получит.\n *\n * Молчать здесь нельзя вдвойне: дерево не просто осталось без ресурса — оно попросило его\n * поимённо и прочло бы отсутствие как промах раскладки.\n */\nconst namedCutLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.namedCut.length\n ? [\n `названо выбором, но не приедет: ${result.namedCut.length}`,\n ...result.namedCut.map((one: ICascadeCut): string => ` ${one.id} — снято вслед за ${one.parent}, отвергнут ${one.root}`),\n ' это предупреждение, а не отказ: возьми родителя в выбор либо убери потомка из него',\n ]\n : [];\n\n/**\n * Файлы ресурсов, ушедших из набора.\n *\n * Названы отдельно от брошенных: брошенный ресурс в наборе есть и вернётся, если дерево его\n * выберет, а снятый не вернётся никогда — и правило, по которому агент работает, у него\n * последнее.\n */\nconst retiredLines: (result: ISyncResult) => string[] = (result: ISyncResult): string[] =>\n result.retired.length\n ? [\n `в дереве лежат файлы ресурсов, которых в пакете больше нет: ${result.retired.length}`,\n ...result.retired.map((one: IRetiredFound): string => ` ${one.path} — снят в v${one.since}: ${one.why}`),\n ' убирает их дерево: в чужие файлы пакет не пишет',\n ]\n : [];\n\n/**\n * Предупреждения раскладки: кода возврата они не меняют и печатаются на любом её исходе.\n *\n * Иначе их не видит никто: на сошедшемся дереве проверка молчит, а удавшаяся раскладка называет\n * положенные файлы — и лишняя строка отказа, снятый каскадом файл и ушедший из набора ресурс\n * всплывали бы только там, где и без них уже красно.\n */\nconst warnings: (result: ISyncResult) => string[] = (result: ISyncResult): string[] => [\n ...brokenLines(result),\n ...idleLines(result),\n ...namedCutLines(result),\n ...retiredLines(result),\n ...cutOnDiskLines(result),\n ...abandonedLines(result),\n];\n\nconst describe: (result: ISyncResult) => string[] = (result: ISyncResult): string[] => [\n ...holes(result),\n ...gapLines(result),\n ...unboundLines(result),\n ...warnings(result),\n ...pendingOf(result).map((entry: IPlanned): string => ` ${entry.path} — ${STATE_WORD[entry.outcome]}`),\n ...unfilled(result).map(companionLine),\n];\n\n/** Имена дырок во всех ресурсах, которые дерево берёт. Без конфига — ни одной: выбор неизвестен. */\nfunction placeholdersIn(config: IConfig | null, assetsDir: string): readonly string[] {\n if (!config) {\n return [];\n }\n const names: string[] = [];\n for (const asset of collectAssets(config, assetsDir)) {\n for (const name of placeholdersOf(asset.text)) {\n if (!names.includes(name)) {\n names.push(name);\n }\n }\n }\n\n return names.sort();\n}\n\n/**\n * Что проект выбрал при заведении конфига. Пустой список — весь набор; выбор приходит сюда\n * готовым, потому что взять его негде, кроме края: у строки запуска флаг, у терминала вопрос,\n * а у неинтерактивного прогона нет ни того ни другого — и решать это команде не по чину.\n */\nexport function init(\n root: string,\n only: readonly string[] = [],\n variants: Readonly<Record<string, string>> = {},\n assetsDir: string = ''\n): IOutcomeOfCommand {\n const path: string = join(root, CONFIG_PATH);\n if (existsSync(path)) {\n return { code: 0, lines: [`${CONFIG_PATH} уже есть — оставлен как есть`] };\n }\n\n const config: object = { vars: {}, layout: DEFAULT_LAYOUT, variants, only, skip: [] };\n mkdirSync(join(root, OVERRIDES_DIR), { recursive: true });\n mkdirSync(join(root, CONFIG_PATH, '..'), { recursive: true });\n writeFileSync(path, `${JSON.stringify(config, null, 4)}\\n`, 'utf8');\n\n // Значения, которых пакет ждёт от дерева, называются здесь, а не отказом раскладки: узнать\n // о них на первом же `sync` значит начать установку с ошибки, притом что список известен\n // сразу — он вычитывается из текстов выбранных ресурсов.\n const wanted: readonly string[] = assetsDir ? placeholdersIn(readConfig(root), assetsDir) : [];\n\n return {\n code: 0,\n lines: [\n `заведён ${CONFIG_PATH}`,\n only.length ? `выбрано ресурсов: ${only.length}` : 'выбрано всё, что везёт пакет',\n ...Object.entries(variants).map(([axis, value]: [string, string]): string => `${axis}: ${value}`),\n `заведён ${OVERRIDES_DIR}/ — надстройки проекта кладутся сюда путём ресурса`,\n ...(wanted.length\n ? [\n `значения, которых ждут ресурсы, — впиши их в \\`vars\\` конфига: ${wanted.length}`,\n ...wanted.map((name: string): string => ` {{${name}}}`),\n ]\n : []),\n 'дальше: `agent-kit sync`, а своё дописывается в `.claude/rt-kit/gate-map.sh` и `project.sh`',\n ],\n };\n}\n\n/**\n * Долг, добавленный этой раскладкой: статьи разложенных правил, у которых в компаньонах дерева\n * нет адреса.\n *\n * Называется он здесь, а не отдельной сверкой, ровно потому, что через день его уже не отличить\n * от накопленного: сверка видит расхождение, но не знает, чьим обновлением оно приехало.\n */\nfunction debtLines(config: IConfig, root: string, assetsDir: string): readonly string[] {\n const found: IUnaddressed[] = [];\n for (const asset of collectAssets(config, assetsDir)) {\n if (asset.kind !== 'rules') {\n continue;\n }\n const path: string = join(root, companionPathOf(asset));\n const existing: string | null = existsSync(path) ? readFileSync(path, 'utf8') : null;\n found.push(unaddressedOf(asset.name, asset.text, existing));\n }\n\n const line: string | null = debtLine(found);\n return line === null ? [] : [line, 'адрес статье дописывается в компаньоне рядом с правилом'];\n}\n\n/**\n * Отказ на устаревшей сборке. Раскладка из неё положила бы прежнюю редакцию ресурса и назвала\n * это сделанным: неправда дороже отказа — её замечают, когда правленое правило не действует.\n */\nconst staleRefusal: (stale: IStaleBuild) => IOutcomeOfCommand = (stale: IStaleBuild): IOutcomeOfCommand => ({\n code: 1,\n lines: [\n 'раскладка не начата: строка запуска читает собранное, а ресурсы правлены позже',\n ` правлено: ${stale.newest}`,\n ` исходные ресурсы: ${stale.source}`,\n ' собери пакет и повтори',\n ],\n});\n\nexport function sync(env: IEnvironment, check: boolean): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n if (env.stale) {\n return staleRefusal(env.stale);\n }\n\n // Ось без ответа отбивает раскладку целиком, а не пропускает свои ресурсы молча: правило\n // поставки бывает в трёх видах, и дерево, не назвавшее свой, осталось бы вовсе без правила\n // поставки — заметить это можно было бы только по тому, что гейт перестал его требовать.\n const unanswered: readonly IAxis[] = unansweredAxes(readAxes(assetsDir), config.variants);\n if (unanswered.length) {\n return { code: 1, lines: ['раскладка не начата: не выбран вид', ...axisLines(unanswered)] };\n }\n\n // Незнакомое свойство — опечатка, и молчать о ней нельзя ни с одной стороны. У дерева она\n // означает, что помеченного им ресурса оно не получит вовсе; у ресурса — что он не ляжет\n // никуда и никогда, а причину в имени файла не разглядеть.\n const strange: readonly string[] = strangeTraits(config, assetsDir);\n if (strange.length) {\n return { code: 1, lines: ['раскладка не начата: свойство дерева не объявлено пакетом', ...strange] };\n }\n\n if (check) {\n const result: ISyncResult = planSync(config, root, version, assetsDir);\n const pending: readonly IPlanned[] = pendingOf(result);\n // Незаполненный компаньон — такое же расхождение, как отставший файл: правило разложено,\n // а имён этого дерева при нём нет, и агент читает указание, которому некуда примениться.\n const empty: readonly ICompanion[] = unfilled(result);\n // Гард, которого не зовёт настройка агента, — такое же расхождение, как отставший файл:\n // он разложен, он коммитится, и по дереву его не отличить от работающего.\n // Разорванная связь в счёт расхождений не идёт: дерево вправе закрыть требование своим\n // средством, и отказ отбивал бы законную раскладку. Но и сходство её не отменяет —\n // предупреждение печатается и там, где расходиться больше нечему.\n const count: number = result.missing.size + result.gaps.length + pending.length + empty.length + result.unbound.length;\n if (!count) {\n return { code: 0, lines: [`sync --check: разложенное сходится с пакетом v${version}`, ...warnings(result)] };\n }\n\n return { code: 1, lines: [`sync --check: расхождений ${count}`, ...describe(result)] };\n }\n\n const result: ISyncResult = runSync(config, root, version, assetsDir);\n // Перечисляются только дырки: раскладка не начата, и назвать файл «положенным» значило бы\n // сказать неправду — на диске его нет.\n if (result.missing.size) {\n return { code: 1, lines: ['раскладка не начата: нечего подставить в дырки', ...holes(result)] };\n }\n\n // Ресурс без вида под выбор дерева отбивает раскладку целиком, а не выпадает из неё молча:\n // правило, разложенное без инструмента, который оно зовёт, читается как действующее.\n if (result.gaps.length) {\n return {\n code: 1,\n lines: ['раскладка не начата: у этих ресурсов нет вида под выбор дерева', ...gapLines(result)],\n };\n }\n\n const refused: readonly IPlanned[] = result.planned.filter((entry: IPlanned): boolean => isRefusal(entry.outcome));\n if (refused.length) {\n return {\n code: 1,\n lines: [\n 'раскладка не начата: эти файлы пакет переписывать не станет',\n ...refused.map((entry: IPlanned): string => ` ${entry.path} — ${DONE_WORD[entry.outcome]}`),\n 'правку надо либо перенести в надстройку, либо снять — и повторить',\n `положенное не пакетом отдаётся ему командой \\`agent-kit adopt\\`: прежнее содержимое ляжет рядом с пометкой \\`${KEPT_SUFFIX}\\``,\n ],\n };\n }\n\n // Раскладка удалась, а гарды могут остаться неподключёнными: настройка агента принадлежит\n // дереву, и пакет в неё не пишет. Код возврата остаётся нулевым — файлы легли, — но молчать\n // об этом нельзя: узнают иначе, когда что-нибудь пройдёт мимо гарда.\n return {\n code: 0,\n lines: [\n ...(result.written.length\n ? [`разложено файлов: ${result.written.length}`, ...result.written.map((path: string): string => ` ${path}`)]\n : ['всё уже разложено']),\n ...unboundLines(result),\n ...debtLines(config, root, assetsDir),\n ...warnings(result),\n ],\n };\n}\n\n/**\n * Отдать пакету файл, который лежит в дереве не от него.\n *\n * Пока команды не было, `sync` отказывал на такой файл поимённо и предлагал «перенести правку в\n * надстройку или снять» — то есть работу, которую делают руками, и до неё же сводилась вся\n * установка в живое дерево. При этом один чужой файл останавливал раскладку целиком.\n *\n * Молчаливой перезаписи здесь нет и быть не может: в файле лежит то, чего в дереве больше нигде\n * нет. Поэтому переход — это переименование прежнего содержимого рядом и повторный `sync`:\n * пакет кладёт своё, а прежнее остаётся на диске под именем с пометкой и ждёт разбора.\n */\nexport function adopt(env: IEnvironment, names: readonly string[]): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n const foreign: readonly IPlanned[] = planSync(config, root, version, assetsDir).planned.filter(\n (entry: IPlanned): boolean => entry.outcome === 'foreign'\n );\n if (!foreign.length) {\n return { code: 0, lines: ['чужих файлов на путях пакета нет'] };\n }\n\n // Имена принимаются как их печатает `sync`: путём в дереве. Без имён отдаются все — на\n // свежей установке их бывает столько же, сколько ресурсов, и перечислять их руками значит\n // делать ту же работу, ради которой команда заведена.\n const wanted: readonly IPlanned[] = names.length\n ? foreign.filter((entry: IPlanned): boolean => names.some((name: string): boolean => entry.path.endsWith(name)))\n : foreign;\n if (!wanted.length) {\n return {\n code: 1,\n lines: ['ни одно имя не отвечает чужому файлу; чужие сейчас такие:', ...foreign.map((e: IPlanned): string => ` ${e.path}`)],\n };\n }\n\n const moved: string[] = [];\n const blocked: string[] = [];\n for (const entry of wanted) {\n const path: string = join(root, entry.path);\n const kept: string = `${path}${KEPT_SUFFIX}`;\n if (existsSync(kept)) {\n blocked.push(` ${entry.path}${KEPT_SUFFIX} — уже лежит, разбери его прежде`);\n continue;\n }\n renameSync(path, kept);\n moved.push(` ${entry.path} → ${entry.path}${KEPT_SUFFIX}`);\n }\n\n return {\n code: blocked.length ? 1 : 0,\n lines: [\n ...(moved.length ? [`прежнее содержимое отложено: ${moved.length}`, ...moved, 'дальше: `agent-kit sync`'] : []),\n ...(blocked.length ? ['не тронуто:', ...blocked] : []),\n ],\n };\n}\n\n/**\n * Сколько незагруженных правил называется поимённо. На коротком отрезке их бывает больше\n * тридцати, и список во весь экран прячет всё остальное, ради чего сводку и открыли.\n */\nconst UNUSED_SHOWN: number = 12;\n\n/** Чем сводка отвечает: отрезок в днях, сегодняшний день и вид вывода. */\nexport interface IStatsOptions {\n readonly days: number;\n /** Сегодняшний день, `ГГГГ-ММ-ДД`. Приходит с края: команду со своими часами не проверить. */\n readonly today: string;\n readonly json: boolean;\n}\n\n/** Столбиком: имя и счёт. Ширина по самому длинному имени — иначе счёт читается по одному. */\nconst countLines: (counted: readonly ICount[]) => string[] = (counted: readonly ICount[]): string[] => {\n const width: number = counted.reduce((found: number, entry: ICount): number => Math.max(found, entry.name.length), 0);\n\n return counted.map((entry: ICount): string => ` ${entry.name.padEnd(width)} ${entry.count}`);\n};\n\n/**\n * Сводка наблюдений за отрезок дней.\n *\n * Отдельная строка про незагруженное — то, ради чего сводка вообще нужна: чем пользуются, видно\n * и по работе, а вот правило, которое не открыли ни разу, ничем себя не выдаёт. Сокращать текст\n * правил так же ценно, как дополнять.\n */\nexport function stats(env: IEnvironment, options: IStatsOptions): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n // Выключенная запись — не пустая сводка: нули на месте наблюдений читаются как «ничего не\n // делали», тогда как на самом деле никто и не смотрел.\n if (!config.observe) {\n return {\n code: 0,\n lines: [\n 'запись наблюдений выключена ключом `observe` в конфиге',\n `включить — убрать ключ или поставить \\`\"observe\": true\\`; пишутся они в ${OBSERVATIONS_DIR}/`,\n ],\n };\n }\n\n const days: number = options.days > 0 ? options.days : DEFAULT_DAYS;\n const result: IReadResult = readObservations(root, options.today, days);\n const summary: ISummary = summarize(result.observations, laidOutSkills(config, assetsDir), days);\n\n if (options.json) {\n return { code: 0, lines: [JSON.stringify({ ...summary, swept: result.swept })] };\n }\n\n if (result.silent) {\n return {\n code: 0,\n lines: [\n 'наблюдений нет: записи не велось ни разу',\n `их пишут гарды в ${OBSERVATIONS_DIR}/ — проверь, что гарды разложены и подключены в ${SETTINGS_PATH}`,\n ],\n };\n }\n\n if (!summary.total) {\n return {\n code: 0,\n lines: [\n `наблюдений за ${days} дн. нет ни одного, а записи велись раньше`,\n ...(result.swept.length ? [`снято по сроку хранения (${KEEP_DAYS} дн.): ${result.swept.length}`] : []),\n 'возьми отрезок длиннее: `--days 14`',\n ],\n };\n }\n\n return {\n code: 0,\n lines: [\n `наблюдения за ${days} дн., заходов ${summary.sessions}, событий ${summary.total}`,\n ...(summary.versions.length ? [`версии пакета в записях: ${summary.versions.join(', ')}`] : []),\n '',\n `правил загружено: ${summary.loads.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.loads),\n ...(summary.unused.length\n ? [\n '',\n `разложено и не загружено ни разу: ${summary.unused.length} из ${laidOutSkills(config, assetsDir).length}`,\n ...summary.unused.slice(0, UNUSED_SHOWN).map((name: string): string => ` ${name}`),\n // Список говорится не весь, и об этом говорится вслух: молчаливый обрыв\n // читается как «вот они все», и правило, не попавшее в первую дюжину,\n // считалось бы работающим.\n ...(summary.unused.length > UNUSED_SHOWN\n ? [` … и ещё ${summary.unused.length - UNUSED_SHOWN} — целиком в \\`--json\\``]\n : []),\n ]\n : []),\n ...(summary.denials.length\n ? [\n '',\n `гейт отбивал: ${summary.denials.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.denials),\n ...(summary.kinds.length\n ? [' чаще всего на:', ...countLines(summary.kinds).map((line: string): string => ` ${line}`)]\n : []),\n ]\n : []),\n ...(summary.guards.length\n ? [\n '',\n `гарды отказывали: ${summary.guards.reduce((found: number, entry: ICount): number => found + entry.count, 0)}`,\n ...countLines(summary.guards),\n ]\n : []),\n ...(result.swept.length ? ['', `снято по сроку хранения (${KEEP_DAYS} дн.): ${result.swept.length}`] : []),\n '',\n `пакет v${version}`,\n ],\n };\n}\n\nexport function doctor(env: IEnvironment): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n if (!config) {\n return { code: 1, lines: [NO_CONFIG] };\n }\n\n const result: ISyncResult = planSync(config, root, version, assetsDir);\n const counted: Map<TOutcome, number> = new Map();\n for (const entry of result.planned) {\n counted.set(entry.outcome, (counted.get(entry.outcome) ?? 0) + 1);\n }\n\n const catalog: readonly IEntryOfCatalog[] = readCatalog(assetsDir);\n const taken: number = collectAssets(config, assetsDir).length;\n const unanswered: readonly IAxis[] = unansweredAxes(readAxes(assetsDir), config.variants);\n const chosen: string[] = Object.entries(config.variants).map(([axis, value]: [string, string]): string => `${axis}: ${value}`);\n // Ресурс чужого вида в «не выбрано» не идёт: проект от него не отказывался — его в этом\n // дереве не существует, как не существует второго правила поставки.\n const foreignVariant: readonly IEntryOfCatalog[] = catalog.filter(\n (entry: IEntryOfCatalog): boolean => entry.variant !== null && config.variants[entry.variant.axis] !== entry.variant.value\n );\n const other: number = foreignVariant.length;\n // Ресурс, названный и в отказе, и чужим видом, считается один раз — иначе «не выбрано»\n // уходит в минус, а минус в отчёте читается как поломка счёта, а не как двойной счёт.\n const skipped: number = config.skip.filter((id: string): boolean =>\n foreignVariant.every((entry: IEntryOfCatalog): boolean => entry.id !== id)\n ).length;\n\n // Снятое каскадом считается и называется отдельно от невыбранного: дерево его не выбирало и\n // не отвергало — оно ушло вслед за родителем, и искать его в отказе читатель пойдёт зря.\n const cuts: readonly ICascadeCut[] = cascadeCuts(catalog, config);\n const cut: ReadonlySet<string> = new Set(cuts.map((one: ICascadeCut): string => one.id));\n\n // Ресурс с неотвеченным требованием в «не выбрано» не идёт по той же причине, что и чужой\n // вид: дерево его не отвергало — свойства, без которого он бессмыслен, у него просто нет.\n const needing: readonly IEntryOfCatalog[] = catalog.filter(\n (entry: IEntryOfCatalog): boolean =>\n entry.needs !== null && !answersRequirement(entry.needs, config.has) && !config.skip.includes(entry.id)\n );\n const needsTrait: number = needing.length;\n\n // Невыбранное называется поимённо: число «не выбрано: 73» не отвечает ни на один вопрос,\n // ради которого его читают, — ни какого ресурса не хватает, ни требуется ли он соседу.\n const unchosen: readonly IEntryOfCatalog[] = catalog.filter(\n (entry: IEntryOfCatalog): boolean =>\n !isChosen(entry, config) &&\n !config.skip.includes(entry.id) &&\n foreignVariant.every((one: IEntryOfCatalog): boolean => one.id !== entry.id) &&\n needing.every((one: IEntryOfCatalog): boolean => one.id !== entry.id)\n );\n\n const lines: string[] = [\n `пакет v${version}, везёт ресурсов ${catalog.length}, взято ${taken}`,\n `не выбрано: ${catalog.length - taken - skipped - other - cut.size - needsTrait}, пропущено: ${skipped}, другой вид: ${other}, снято каскадом: ${cut.size}, нужно свойство: ${needsTrait}`,\n ...unchosen.map((entry: IEntryOfCatalog): string => ` не выбран: ${entry.id}`),\n ...needing.map((entry: IEntryOfCatalog): string => ` нужно свойство «${entry.needs}»: ${entry.id}`),\n ...cuts.map(\n (one: ICascadeCut): string =>\n ` снят каскадом: ${one.id} — вслед за ${one.parent}${one.parent === one.root ? '' : `, отвергнут ${one.root}`}`\n ),\n ...profileLines(root, assetsDir, config),\n `значений в конфиге: ${Object.keys(config.vars).length}`,\n ...chosen,\n ...[...counted].map(([outcome, count]: [TOutcome, number]): string => `${STATE_WORD[outcome]}: ${count}`),\n ...describe(result),\n ...(unanswered.length ? ['не выбран вид — раскладка не начнётся:', ...axisLines(unanswered)] : []),\n // Про устаревшую сборку `doctor` говорит, но отказом её не считает: он ничего не пишет,\n // и прочитать состояние дерева можно и из вчерашней сборки — знать бы, что она вчерашняя.\n ...(env.stale ? ['собранное отстало от исходников — раскладка откажет:', ` правлено: ${env.stale.newest}`] : []),\n ];\n\n return { code: 0, lines };\n}\n\n/**\n * Что пакет везёт и что из этого взято здесь.\n *\n * Работает и без конфига: посмотреть, из чего выбирать, нужно раньше, чем выбор сделан, — иначе\n * имена законов взять неоткуда, кроме исходников пакета.\n */\nexport function list(env: IEnvironment): IOutcomeOfCommand {\n const { root, version, assetsDir } = env;\n const config: IConfig | null = readConfig(root);\n const catalog: readonly IEntryOfCatalog[] = readCatalog(assetsDir);\n const planned: Map<string, TOutcome> = new Map();\n const cutByCascade: ReadonlySet<string> = new Set(config ? cascadeCuts(catalog, config).map((one: ICascadeCut): string => one.id) : []);\n\n if (config) {\n for (const entry of planSync(config, root, version, assetsDir).planned) {\n planned.set(entry.asset, entry.outcome);\n }\n }\n\n const stateOf: (entry: IEntryOfCatalog) => string = (entry: IEntryOfCatalog): string => {\n if (!config) {\n return 'везёт пакет';\n }\n if (entry.variant && config.variants[entry.variant.axis] !== entry.variant.value) {\n return OTHER_VARIANT;\n }\n if (config.skip.includes(entry.id)) {\n return SKIPPED;\n }\n // Неотвеченное требование — не отказ дерева: оно этого ресурса не выбирало и не\n // отвергало, а свойства, без которого ресурс бессмыслен, у него просто нет.\n if (entry.needs !== null && !answersRequirement(entry.needs, config.has)) {\n return `${NEEDS_TRAIT}: ${entry.needs}`;\n }\n if (!isChosen(entry, config)) {\n return NOT_CHOSEN;\n }\n if (cutByCascade.has(entry.id)) {\n return CUT_BY_CASCADE;\n }\n const outcome: TOutcome | undefined = planned.get(entry.id);\n\n // Ресурса нет среди запланированных ровно в одном случае: в нём осталась дырка без\n // значения, и до решения о судьбе файла раскладка не дошла.\n return outcome ? STATE_WORD[outcome] : 'дырка без значения';\n };\n\n const name: number = catalog.reduce((found: number, entry: IEntryOfCatalog): number => Math.max(found, entry.name.length), 0);\n const state: number = catalog.reduce((found: number, entry: IEntryOfCatalog): number => Math.max(found, stateOf(entry).length), 0);\n const lines: string[] = [config ? `пакет v${version}` : `пакет v${version}, ${CONFIG_PATH} ещё не заведён`];\n\n for (const kind of KINDS) {\n const entries: readonly IEntryOfCatalog[] = catalog.filter((entry: IEntryOfCatalog): boolean => entry.kind === kind);\n if (!entries.length) {\n continue;\n }\n lines.push('', KIND_TITLE[kind]);\n lines.push(\n ...entries.map(\n (entry: IEntryOfCatalog): string => ` ${entry.name.padEnd(name)} ${stateOf(entry).padEnd(state)} ${entry.title}`\n )\n );\n }\n\n return { code: 0, lines };\n}\n"]}
|
package/lib/companion.d.ts
CHANGED
|
@@ -34,6 +34,14 @@ export interface ICompanion {
|
|
|
34
34
|
readonly state: TCompanionState;
|
|
35
35
|
/** Что записать; `null` — писать нечего, файл уже лежит. */
|
|
36
36
|
readonly content: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Свойство дерева, которого требует правило, — `null`, если не требует ничего.
|
|
39
|
+
*
|
|
40
|
+
* Нужно ровно на отказе: пустой компаньон правила, которому дерево не отвечает, — не долг, а
|
|
41
|
+
* лишний файл, и предлагать его заполнить значит звать на работу, которой нет. Такое правило
|
|
42
|
+
* доезжает до дерева только выбором поимённо: требование само по себе его не кладёт.
|
|
43
|
+
*/
|
|
44
|
+
readonly needs: string | null;
|
|
37
45
|
}
|
|
38
46
|
/** Путь компаньона: рядом с самим правилом, в каталоге его имени. */
|
|
39
47
|
export declare const pathOf: (asset: IAsset) => string;
|
|
@@ -54,4 +62,33 @@ export declare const draftOf: (template: string, rule: string, text?: string) =>
|
|
|
54
62
|
export declare function planCompanion(asset: IAsset, existing: string | null, template: string): ICompanion;
|
|
55
63
|
/** Что `sync --check` считает недоделанным: правило при пустом компаньоне не действует. */
|
|
56
64
|
export declare const isUnfilled: (companion: ICompanion) => boolean;
|
|
65
|
+
/** Долг, добавленный обновлением: статьи правила, у которых в компаньоне дерева нет адреса. */
|
|
66
|
+
export interface IUnaddressed {
|
|
67
|
+
/** Имя правила, чьи статьи считались. */
|
|
68
|
+
readonly rule: string;
|
|
69
|
+
/** Сколько статей у правила всего. */
|
|
70
|
+
readonly total: number;
|
|
71
|
+
/** Статьи, которых в компаньоне нет. */
|
|
72
|
+
readonly missing: readonly string[];
|
|
73
|
+
/** Компаньона рядом с правилом нет вовсе: долг здесь — все статьи разом. */
|
|
74
|
+
readonly absent: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Счёт статей без адреса. Отделён от записи файлов намеренно: раскладка кладёт их на диск, а
|
|
78
|
+
* решение о том, что назвать добавленным долгом, к записи не привязано и проверяется без
|
|
79
|
+
* файловой системы.
|
|
80
|
+
*
|
|
81
|
+
* Статья ищется в компаньоне дословно — её текст и есть ключ связи, тот же, которым сверяются
|
|
82
|
+
* привязки. Переписанная руками, она расходится с правилом молча, и здесь это видно сразу:
|
|
83
|
+
* такая статья считается ненайденной.
|
|
84
|
+
*/
|
|
85
|
+
export declare function unaddressedOf(rule: string, text: string, existing: string | null): IUnaddressed;
|
|
86
|
+
/**
|
|
87
|
+
* Строка о добавленном долге для вывода раскладки. Молчит, когда долга нет: строка «статей без
|
|
88
|
+
* адреса: 0» приходила бы при каждой раскладке и перестала бы читаться.
|
|
89
|
+
*
|
|
90
|
+
* Долг называется числом, а не списком: двадцать девять строк в выводе не читают, а сами статьи
|
|
91
|
+
* стоят в компаньоне, куда за ними и идут.
|
|
92
|
+
*/
|
|
93
|
+
export declare function debtLine(found: readonly IUnaddressed[]): string | null;
|
|
57
94
|
//# sourceMappingURL=companion.d.ts.map
|
package/lib/companion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/companion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"companion.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/companion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAoC,CAAC;AAElE,MAAM,MAAM,eAAe;AACvB,wEAAwE;AACtE,SAAS;AACX,8CAA8C;GAC5C,OAAO;AACT,2BAA2B;GACzB,QAAQ,CAAC;AAEf,MAAM,WAAW,UAAU;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,qEAAqE;AACrE,eAAO,MAAM,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAkF,CAAC;AAE3H;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,MAAwB,CAAC;AAoBjD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,MAgBxE,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAclG;AAED,2FAA2F;AAC3F,eAAO,MAAM,UAAU,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAA0E,CAAC;AAE/H,+FAA+F;AAC/F,MAAM,WAAW,YAAY;IACzB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,CAY/F;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,GAAG,IAAI,CAWtE"}
|
package/lib/companion.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { COMPANION_FILE } from './config.js';
|
|
2
|
+
import { requirementOf } from './traits.js';
|
|
2
3
|
/**
|
|
3
4
|
* Метка незаполненного места. Стоит в каждой строке черновика, которую должен заменить проект,
|
|
4
5
|
* и снимается вместе с ней: пока метка на месте, компаньон не заполнен.
|
|
@@ -45,16 +46,56 @@ export const draftOf = (template, rule, text = '') => {
|
|
|
45
46
|
};
|
|
46
47
|
export function planCompanion(asset, existing, template) {
|
|
47
48
|
const path = pathOf(asset);
|
|
49
|
+
const needs = requirementOf(asset.id);
|
|
48
50
|
if (existing === null) {
|
|
49
|
-
return { rule: asset.name, path, state: 'missing', content: draftOf(template, asset.name, asset.text) };
|
|
51
|
+
return { rule: asset.name, path, state: 'missing', content: draftOf(template, asset.name, asset.text), needs };
|
|
50
52
|
}
|
|
51
53
|
return {
|
|
52
54
|
rule: asset.name,
|
|
53
55
|
path,
|
|
54
56
|
state: existing.includes(COMPANION_MARK) ? 'draft' : 'filled',
|
|
55
57
|
content: null,
|
|
58
|
+
needs,
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
/** Что `sync --check` считает недоделанным: правило при пустом компаньоне не действует. */
|
|
59
62
|
export const isUnfilled = (companion) => companion.state !== 'filled';
|
|
63
|
+
/**
|
|
64
|
+
* Счёт статей без адреса. Отделён от записи файлов намеренно: раскладка кладёт их на диск, а
|
|
65
|
+
* решение о том, что назвать добавленным долгом, к записи не привязано и проверяется без
|
|
66
|
+
* файловой системы.
|
|
67
|
+
*
|
|
68
|
+
* Статья ищется в компаньоне дословно — её текст и есть ключ связи, тот же, которым сверяются
|
|
69
|
+
* привязки. Переписанная руками, она расходится с правилом молча, и здесь это видно сразу:
|
|
70
|
+
* такая статья считается ненайденной.
|
|
71
|
+
*/
|
|
72
|
+
export function unaddressedOf(rule, text, existing) {
|
|
73
|
+
const statements = statementsOf(text);
|
|
74
|
+
if (existing === null) {
|
|
75
|
+
return { rule, total: statements.length, missing: statements, absent: true };
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
rule,
|
|
79
|
+
total: statements.length,
|
|
80
|
+
missing: statements.filter((statement) => !existing.includes(statement)),
|
|
81
|
+
absent: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Строка о добавленном долге для вывода раскладки. Молчит, когда долга нет: строка «статей без
|
|
86
|
+
* адреса: 0» приходила бы при каждой раскладке и перестала бы читаться.
|
|
87
|
+
*
|
|
88
|
+
* Долг называется числом, а не списком: двадцать девять строк в выводе не читают, а сами статьи
|
|
89
|
+
* стоят в компаньоне, куда за ними и идут.
|
|
90
|
+
*/
|
|
91
|
+
export function debtLine(found) {
|
|
92
|
+
const withDebt = found.filter((entry) => entry.missing.length > 0);
|
|
93
|
+
if (!withDebt.length) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const statements = withDebt.reduce((sum, entry) => sum + entry.missing.length, 0);
|
|
97
|
+
const absent = withDebt.filter((entry) => entry.absent).length;
|
|
98
|
+
const tail = absent ? `, из них ${absent} без компаньона вовсе` : '';
|
|
99
|
+
return `статей без адреса: ${statements} в ${withDebt.length} компаньонах${tail}`;
|
|
100
|
+
}
|
|
60
101
|
//# sourceMappingURL=companion.js.map
|
package/lib/companion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/companion.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAW,2BAA2B,CAAC;AAmBlE,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAA8B,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;AAE3H;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAW,eAAe,CAAC;AAEjD,wFAAwF;AACxF,MAAM,aAAa,GAAW,qEAAqE,CAAC;AAEpG;;;GAGG;AACH,SAAS,YAAY,CAAC,IAAY;IAC9B,MAAM,OAAO,GAA4B,IAAI,CAAC,KAAK,CAC/C,yFAAyF,CAC5F,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACd,CAAC;IAED,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAuB,EAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AACpH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAA8D,CAC9E,QAAgB,EAChB,IAAY,EACZ,OAAe,EAAE,EACX,EAAE;IACR,MAAM,KAAK,GAAW,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAsB,YAAY,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,GAAW,UAAU;SAC1B,GAAG,CAAC,CAAC,SAAiB,EAAU,EAAE,CAAC,KAAK,SAAS,0BAA0B,cAAc,IAAI,CAAC;SAC9F,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtF,CAAC,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,QAAuB,EAAE,QAAgB;IAClF,MAAM,IAAI,GAAW,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5G,CAAC;IAED,OAAO;QACH,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI;QACJ,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;QAC7D,OAAO,EAAE,IAAI;KAChB,CAAC;AACN,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,MAAM,UAAU,GAAuC,CAAC,SAAqB,EAAW,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,QAAQ,CAAC","sourcesContent":["/**\n * Файл-компаньон правила: чем названо в этом дереве то, о чём правило говорит приёмом.\n *\n * Правило пакета переносимо ровно потому, что не знает ни путей, ни имён: оно говорит, какой\n * приём здесь действует и что сломается без него. Но правило без имён дерева — это закон, и\n * агент по нему работать не может: ему нужно знать, как называется здесь то, о чём идёт речь,\n * и где оно лежит.\n *\n * Поэтому имена живут рядом с правилом, в отдельном файле, и пишет его проект. Пакет кладёт\n * черновик один раз и больше к нему не возвращается: сверять его нечем — своего текста у пакета\n * там нет, а перекладывать значило бы стирать написанное проектом.\n *\n * Отсюда и три состояния вместо двух. Черновик, который никто не заполнил, — не то же самое,\n * что заполненный компаньон, и не то же самое, что пропавший: он выглядит рабочим файлом, но\n * правило при нём остаётся указанием без адресата.\n */\nimport { IAsset } from './assets.js';\nimport { COMPANION_FILE } from './config.js';\n\n/**\n * Метка незаполненного места. Стоит в каждой строке черновика, которую должен заменить проект,\n * и снимается вместе с ней: пока метка на месте, компаньон не заполнен.\n */\nexport const COMPANION_MARK: string = '<!-- заполняет проект -->';\n\nexport type TCompanionState =\n /** Файла нет: правило разложено, а имён дерева при нём не оказалось. */\n | 'missing'\n /** Черновик лежит, но остался как положен. */\n | 'draft'\n /** Проект его заполнил. */\n | 'filled';\n\nexport interface ICompanion {\n /** Правило, при котором стоит компаньон. */\n readonly rule: string;\n readonly path: string;\n readonly state: TCompanionState;\n /** Что записать; `null` — писать нечего, файл уже лежит. */\n readonly content: string | null;\n}\n\n/** Путь компаньона: рядом с самим правилом, в каталоге его имени. */\nexport const pathOf: (asset: IAsset) => string = (asset: IAsset): string => asset.target.replace(/[^/]+$/, COMPANION_FILE);\n\n/**\n * Место имени правила в шаблоне. Угловые скобки, а не `{{дырка}}`: дырка без значения отказывает\n * раскладке, а шаблон компаньона пакет кладёт проекту и сам — на нём раскладка и споткнулась бы.\n */\nexport const RULE_SLOT: string = '<имя-правила>';\n\n/** Строка таблицы «Где исполняются статьи»: статья дословно и пустое место под путь. */\nconst STATEMENT_ROW: string = '| <статья дословно> | `<путь>:<символ>` <!-- заполняет проект --> |';\n\n/**\n * Статьи правила — жирные фразы, которыми начинается каждый пункт раздела о применении закона.\n * Раздел называется по-разному у правила пакета и у развёрнутого в дереве, поэтому берутся оба.\n */\nfunction statementsOf(rule: string): readonly string[] {\n const section: RegExpMatchArray | null = rule.match(\n /^## (?:Как закон применяется здесь|Что здесь действует)$([\\s\\S]*?)(?=^## |$(?![\\s\\S]))/m\n );\n if (!section) {\n return [];\n }\n\n return [...section[1].matchAll(/^- \\*\\*(.+?)\\*\\*/gm)].map((found: RegExpMatchArray): string => found[1].trim());\n}\n\n/**\n * Черновик по шаблону пакета. Имя правила подставляется, чтобы заполняющий не гадал, к чему\n * файл относится, — открывают его обычно из гейта, а не из правила.\n *\n * Статьи правила переносятся в таблицу заранее: их текст — ключ связи, и переписанный руками он\n * расходится с правилом молча. Проекту остаётся вторая колонка, а не перепечатывание первой:\n * двадцать пять компаньонов на первой установке — это работа, и половина её механическая.\n */\nexport const draftOf: (template: string, rule: string, text?: string) => string = (\n template: string,\n rule: string,\n text: string = ''\n): string => {\n const draft: string = template.split(RULE_SLOT).join(rule);\n const statements: readonly string[] = statementsOf(text);\n if (!statements.length) {\n return draft;\n }\n\n const rows: string = statements\n .map((statement: string): string => `| ${statement} | \\`<путь>:<символ>\\` ${COMPANION_MARK} |`)\n .join('\\n');\n\n return draft.includes(STATEMENT_ROW) ? draft.replace(STATEMENT_ROW, rows) : draft;\n};\n\nexport function planCompanion(asset: IAsset, existing: string | null, template: string): ICompanion {\n const path: string = pathOf(asset);\n if (existing === null) {\n return { rule: asset.name, path, state: 'missing', content: draftOf(template, asset.name, asset.text) };\n }\n\n return {\n rule: asset.name,\n path,\n state: existing.includes(COMPANION_MARK) ? 'draft' : 'filled',\n content: null,\n };\n}\n\n/** Что `sync --check` считает недоделанным: правило при пустом компаньоне не действует. */\nexport const isUnfilled: (companion: ICompanion) => boolean = (companion: ICompanion): boolean => companion.state !== 'filled';\n"]}
|
|
1
|
+
{"version":3,"file":"companion.js","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/companion.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Файл-компаньон правила: чем названо в этом дереве то, о чём правило говорит приёмом.\n *\n * Правило пакета переносимо ровно потому, что не знает ни путей, ни имён: оно говорит, какой\n * приём здесь действует и что сломается без него. Но правило без имён дерева — это закон, и\n * агент по нему работать не может: ему нужно знать, как называется здесь то, о чём идёт речь,\n * и где оно лежит.\n *\n * Поэтому имена живут рядом с правилом, в отдельном файле, и пишет его проект. Пакет кладёт\n * черновик один раз и больше к нему не возвращается: сверять его нечем — своего текста у пакета\n * там нет, а перекладывать значило бы стирать написанное проектом.\n *\n * Отсюда и три состояния вместо двух. Черновик, который никто не заполнил, — не то же самое,\n * что заполненный компаньон, и не то же самое, что пропавший: он выглядит рабочим файлом, но\n * правило при нём остаётся указанием без адресата.\n */\nimport { IAsset } from './assets.js';\nimport { COMPANION_FILE } from './config.js';\nimport { requirementOf } from './traits.js';\n\n/**\n * Метка незаполненного места. Стоит в каждой строке черновика, которую должен заменить проект,\n * и снимается вместе с ней: пока метка на месте, компаньон не заполнен.\n */\nexport const COMPANION_MARK: string = '<!-- заполняет проект -->';\n\nexport type TCompanionState =\n /** Файла нет: правило разложено, а имён дерева при нём не оказалось. */\n | 'missing'\n /** Черновик лежит, но остался как положен. */\n | 'draft'\n /** Проект его заполнил. */\n | 'filled';\n\nexport interface ICompanion {\n /** Правило, при котором стоит компаньон. */\n readonly rule: string;\n readonly path: string;\n readonly state: TCompanionState;\n /** Что записать; `null` — писать нечего, файл уже лежит. */\n readonly content: string | null;\n /**\n * Свойство дерева, которого требует правило, — `null`, если не требует ничего.\n *\n * Нужно ровно на отказе: пустой компаньон правила, которому дерево не отвечает, — не долг, а\n * лишний файл, и предлагать его заполнить значит звать на работу, которой нет. Такое правило\n * доезжает до дерева только выбором поимённо: требование само по себе его не кладёт.\n */\n readonly needs: string | null;\n}\n\n/** Путь компаньона: рядом с самим правилом, в каталоге его имени. */\nexport const pathOf: (asset: IAsset) => string = (asset: IAsset): string => asset.target.replace(/[^/]+$/, COMPANION_FILE);\n\n/**\n * Место имени правила в шаблоне. Угловые скобки, а не `{{дырка}}`: дырка без значения отказывает\n * раскладке, а шаблон компаньона пакет кладёт проекту и сам — на нём раскладка и споткнулась бы.\n */\nexport const RULE_SLOT: string = '<имя-правила>';\n\n/** Строка таблицы «Где исполняются статьи»: статья дословно и пустое место под путь. */\nconst STATEMENT_ROW: string = '| <статья дословно> | `<путь>:<символ>` <!-- заполняет проект --> |';\n\n/**\n * Статьи правила — жирные фразы, которыми начинается каждый пункт раздела о применении закона.\n * Раздел называется по-разному у правила пакета и у развёрнутого в дереве, поэтому берутся оба.\n */\nfunction statementsOf(rule: string): readonly string[] {\n const section: RegExpMatchArray | null = rule.match(\n /^## (?:Как закон применяется здесь|Что здесь действует)$([\\s\\S]*?)(?=^## |$(?![\\s\\S]))/m\n );\n if (!section) {\n return [];\n }\n\n return [...section[1].matchAll(/^- \\*\\*(.+?)\\*\\*/gm)].map((found: RegExpMatchArray): string => found[1].trim());\n}\n\n/**\n * Черновик по шаблону пакета. Имя правила подставляется, чтобы заполняющий не гадал, к чему\n * файл относится, — открывают его обычно из гейта, а не из правила.\n *\n * Статьи правила переносятся в таблицу заранее: их текст — ключ связи, и переписанный руками он\n * расходится с правилом молча. Проекту остаётся вторая колонка, а не перепечатывание первой:\n * двадцать пять компаньонов на первой установке — это работа, и половина её механическая.\n */\nexport const draftOf: (template: string, rule: string, text?: string) => string = (\n template: string,\n rule: string,\n text: string = ''\n): string => {\n const draft: string = template.split(RULE_SLOT).join(rule);\n const statements: readonly string[] = statementsOf(text);\n if (!statements.length) {\n return draft;\n }\n\n const rows: string = statements\n .map((statement: string): string => `| ${statement} | \\`<путь>:<символ>\\` ${COMPANION_MARK} |`)\n .join('\\n');\n\n return draft.includes(STATEMENT_ROW) ? draft.replace(STATEMENT_ROW, rows) : draft;\n};\n\nexport function planCompanion(asset: IAsset, existing: string | null, template: string): ICompanion {\n const path: string = pathOf(asset);\n const needs: string | null = requirementOf(asset.id);\n if (existing === null) {\n return { rule: asset.name, path, state: 'missing', content: draftOf(template, asset.name, asset.text), needs };\n }\n\n return {\n rule: asset.name,\n path,\n state: existing.includes(COMPANION_MARK) ? 'draft' : 'filled',\n content: null,\n needs,\n };\n}\n\n/** Что `sync --check` считает недоделанным: правило при пустом компаньоне не действует. */\nexport const isUnfilled: (companion: ICompanion) => boolean = (companion: ICompanion): boolean => companion.state !== 'filled';\n\n/** Долг, добавленный обновлением: статьи правила, у которых в компаньоне дерева нет адреса. */\nexport interface IUnaddressed {\n /** Имя правила, чьи статьи считались. */\n readonly rule: string;\n /** Сколько статей у правила всего. */\n readonly total: number;\n /** Статьи, которых в компаньоне нет. */\n readonly missing: readonly string[];\n /** Компаньона рядом с правилом нет вовсе: долг здесь — все статьи разом. */\n readonly absent: boolean;\n}\n\n/**\n * Счёт статей без адреса. Отделён от записи файлов намеренно: раскладка кладёт их на диск, а\n * решение о том, что назвать добавленным долгом, к записи не привязано и проверяется без\n * файловой системы.\n *\n * Статья ищется в компаньоне дословно — её текст и есть ключ связи, тот же, которым сверяются\n * привязки. Переписанная руками, она расходится с правилом молча, и здесь это видно сразу:\n * такая статья считается ненайденной.\n */\nexport function unaddressedOf(rule: string, text: string, existing: string | null): IUnaddressed {\n const statements: readonly string[] = statementsOf(text);\n if (existing === null) {\n return { rule, total: statements.length, missing: statements, absent: true };\n }\n\n return {\n rule,\n total: statements.length,\n missing: statements.filter((statement: string): boolean => !existing.includes(statement)),\n absent: false,\n };\n}\n\n/**\n * Строка о добавленном долге для вывода раскладки. Молчит, когда долга нет: строка «статей без\n * адреса: 0» приходила бы при каждой раскладке и перестала бы читаться.\n *\n * Долг называется числом, а не списком: двадцать девять строк в выводе не читают, а сами статьи\n * стоят в компаньоне, куда за ними и идут.\n */\nexport function debtLine(found: readonly IUnaddressed[]): string | null {\n const withDebt: readonly IUnaddressed[] = found.filter((entry: IUnaddressed): boolean => entry.missing.length > 0);\n if (!withDebt.length) {\n return null;\n }\n\n const statements: number = withDebt.reduce((sum: number, entry: IUnaddressed): number => sum + entry.missing.length, 0);\n const absent: number = withDebt.filter((entry: IUnaddressed): boolean => entry.absent).length;\n const tail: string = absent ? `, из них ${absent} без компаньона вовсе` : '';\n\n return `статей без адреса: ${statements} в ${withDebt.length} компаньонах${tail}`;\n}\n"]}
|