UNPKG

aiwg

Version:

Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo

97 lines 4.81 kB
/** * AIWG.md generator — content-rich CLAUDE.md companion for non-Claude providers. * * Per ADR-1 §0.5: AIWG.md at project root has the same content shape as * CLAUDE.md. Both files `@`-reference the project's `.aiwg/AIWG.md` (the * source of truth). Non-Claude providers reach AIWG.md transitively via the * AGENTS.md `## Framework Context` link. The two project-root files contain * identical framework prose; they exist as two named files because Claude * Code looks for `CLAUDE.md` and the seven AGENTS.md providers reach * AIWG.md via the AGENTS.md hook-up. * * Generation strategy: read the project's CLAUDE.md (which already exists in * a properly-configured repo) and emit AIWG.md as the same content with the * AIWG signature comment in place. If CLAUDE.md is absent (early-init repos), * fall back to a minimal stub that points readers at `.aiwg/AIWG.md`. */ import { promises as fs } from 'node:fs'; import * as path from 'node:path'; import { buildParallelismSection, replaceOrAppendParallelismBlock } from './parallelism-section.js'; import { buildContextFinalizationBlock, replaceOrAppendFinalizationBlock } from './finalization.js'; const AIWG_SIGNATURE_COMMENT = '<!-- aiwg-managed -->'; /** * Build the AIWG.md content for emission at project root. * * - When CLAUDE.md exists at project root: copy its content with the AIWG * signature comment inserted in the second line so future runs of the * generator know the file is AIWG-managed. * - When CLAUDE.md does not exist: emit a minimal stub directing readers to * the project's `.aiwg/AIWG.md` source. * * Returns the rendered content as a string. Caller is responsible for the * atomic-write emission and the operator-claimed-file detection. */ export async function buildAiwgMdContent(projectPath) { const claudeMdPath = path.join(projectPath, 'CLAUDE.md'); let claudeMdContent = null; try { claudeMdContent = await fs.readFile(claudeMdPath, 'utf8'); } catch (err) { if (err.code !== 'ENOENT') { throw err; } } // #1362: parallelism cap section, injected after generation so it surfaces // in regenerated context files regardless of CLAUDE.md content. const parallelismSection = await buildParallelismSection(projectPath); const finalizationBlock = await buildContextFinalizationBlock(projectPath); if (claudeMdContent) { // Insert the AIWG signature comment as the second line. // Top line is typically `# AIWG` or `# Project` heading; preserve it. const lines = claudeMdContent.split('\n'); // #1268: strip `@AIWG.md` self-include directives. CLAUDE.md uses // `@AIWG.md` to pull in the framework context; AIWG.md IS that framework // context, so the directive becomes a self-reference when copied through. // Match the directive when it appears on its own line (possibly indented). const SELF_INCLUDE_PATTERN = /^\s*@AIWG\.md\s*$/; const filtered = lines.filter((line) => !SELF_INCLUDE_PATTERN.test(line)); const firstLine = filtered[0] ?? ''; const rest = filtered.slice(1); // If the file already carries the signature elsewhere, don't double-insert. const alreadySigned = filtered.slice(0, 4).some((l) => l.includes(AIWG_SIGNATURE_COMMENT)); const baseContent = alreadySigned ? filtered.join('\n') : [ firstLine, AIWG_SIGNATURE_COMMENT, '<!-- AIWG.md is the CLAUDE.md companion for non-Claude providers; same content. -->', ...rest, ].join('\n'); const withParallelism = replaceOrAppendParallelismBlock(baseContent, parallelismSection); return replaceOrAppendFinalizationBlock(withParallelism, finalizationBlock); } // Fallback stub. const stub = [ '# AIWG.md', AIWG_SIGNATURE_COMMENT, '<!-- CLAUDE.md companion for non-Claude providers. -->', '', 'CLAUDE.md was not found at project root. AIWG.md normally mirrors that content.', 'See [.aiwg/AIWG.md](./.aiwg/AIWG.md) for the project framework context.', '', ].join('\n'); const withParallelism = replaceOrAppendParallelismBlock(stub, parallelismSection); return replaceOrAppendFinalizationBlock(withParallelism, finalizationBlock); } /** * Public API: build AIWG.md content for a given project. * * The wrapper exists so future variants (per-provider AIWG.md customization, * AIWG.local.md operator overrides, etc.) have a single entry point in the * surface API without callers reaching into the implementation. */ export async function generateAiwgMd(projectPath) { return buildAiwgMdContent(projectPath); } //# sourceMappingURL=aiwg-md.js.map