import { b as CanonicalFiles, c as CanonicalRule, V as ValidatedConfig, E as ExtendPick } from './schema-CzaoYJlG.js'; /** Result of generating files for a target */ interface GenerateResult { /** Target tool ID */ target: string; /** File path (relative to project root) */ path: string; /** File content (what would be written) */ content: string; /** Current on-disk content, set when status is updated or unchanged */ currentContent?: string; /** What happened: created, updated, unchanged, skipped */ status: 'created' | 'updated' | 'unchanged' | 'skipped'; /** If skipped, why */ skipReason?: string; } /** Result of importing from a tool */ interface ImportResult { /** Source tool */ fromTool: string; /** Source file path */ fromPath: string; /** Destination canonical path */ toPath: string; /** What was imported */ feature: string; } /** Lint diagnostic */ interface LintDiagnostic { level: 'error' | 'warning'; file: string; target: string; message: string; } /** Feature support level per target */ type SupportLevel = 'native' | 'embedded' | 'partial' | 'none'; /** * Generated catalog of builtin target IDs (directory names under `src/targets/`). * No descriptor imports — keeps this module on the schema-safe side of the * `schema.ts → descriptors → ValidatedConfig → schema.ts` cycle. */ declare const BUILTIN_TARGET_IDS: readonly ["aider", "amazon-q", "amp", "antigravity", "augment-code", "claude-code", "cline", "codex-cli", "continue", "copilot", "crush", "cursor", "deepagents-cli", "factory-droid", "gemini-cli", "goose", "jules", "junie", "kilo-code", "kiro", "opencode", "pi-agent", "qwen-code", "replit-agent", "roo-code", "rovodev", "trae", "warp", "windsurf", "zed"]; type BuiltinTargetId = (typeof BUILTIN_TARGET_IDS)[number]; /** Serialization / projection variant for a canonical feature (see architecture review §3.3). */ type FeatureFlavor = 'standard' | 'workflows' | 'settings-embedded' | 'projected-skills' | 'gh-actions-lite' | string; /** Normalized capability entry: support level plus optional serialization flavor. */ interface TargetCapabilityValue { readonly level: SupportLevel; readonly flavor?: FeatureFlavor; } /** Descriptor may still use legacy string levels until fully migrated — normalize on read. */ type TargetCapabilityInput = SupportLevel | TargetCapabilityValue; /** * Capabilities of a target tool — each feature has a level and optional serialization flavor. * String levels are accepted for authoring; `getTargetCapabilities` normalizes to objects. * * The matching `SupportLevel` union lives in `core/types.ts` (`'native' | 'embedded' | * 'partial' | 'none'`); every external consumer imports it from there. */ type TargetCapabilities = Record<'rules' | 'additionalRules' | 'commands' | 'agents' | 'skills' | 'mcp' | 'hooks' | 'ignore' | 'permissions', TargetCapabilityInput>; /** Optional context passed to feature generators (flavor-aware targets). */ interface GenerateFeatureContext { readonly capability: TargetCapabilityValue; readonly scope: TargetLayoutScope; } type FeatureGeneratorOutput = { path: string; content: string; }; type FeatureGeneratorFn = (canonical: CanonicalFiles, ctx?: GenerateFeatureContext) => FeatureGeneratorOutput[]; /** * Per-feature generator contract matching engine.ts dispatch tables. * Each generator takes CanonicalFiles and returns file outputs. * Only generateRules and importFrom are required; all others are optional * because not every target supports every feature. */ interface TargetGenerators { name: string; primaryRootInstructionPath?: string; generateRules: FeatureGeneratorFn; generateCommands?: FeatureGeneratorFn; generateAgents?: FeatureGeneratorFn; generateSkills?: FeatureGeneratorFn; generateMcp?: FeatureGeneratorFn; generatePermissions?: FeatureGeneratorFn; generateHooks?: FeatureGeneratorFn; generateIgnore?: FeatureGeneratorFn; importFrom(projectRoot: string, options?: { scope?: TargetLayoutScope; }): Promise; lint?(files: CanonicalFiles): LintDiagnostic[]; } /** * Descriptor-driven importer contract. * * Each target may declare an `importer: TargetImporterDescriptor` block on its * descriptor. The shared runner walks the spec, resolves sources for the active * scope, and dispatches to existing helpers (`importFileDirectory`, * `importDirectorySkill`, …). Scope variance is expressed as data — features * with no `global` source are silently skipped in global mode, eliminating the * `if (scope === 'global')` branches that previously leaked into importer bodies. * * Targets with custom parsing (codex-cli rule splitter, windsurf workflows, * gemini-cli policies) keep their own `generators.importFrom` and may also * delegate the declarable parts of their flow to the runner. */ /** * Per-scope source paths. Omit `global` to make the feature project-only — the * runner skips it under `--global` instead of every importer guarding with * `if (scope === 'global')`. */ interface ImportSourcePaths { readonly project?: readonly string[]; readonly global?: readonly string[]; } type ImportFeatureKind = 'rules' | 'commands' | 'agents' | 'skills' | 'mcp' | 'hooks' | 'permissions' | 'ignore'; /** * Mapping modes: * - `singleFile` — try each `source` path in order, take the first that * exists, write to `${canonicalDir}/${canonicalRootFilename}`. * Used for root rule files (`AGENTS.md`, `CLAUDE.md`, …). * - `directory` — recurse `source` paths and run a per-entry mapper. Built * on top of the existing `importFileDirectory` helper. * - `flatFile` — copy a single file verbatim (with `trimEnd`) to a fixed * canonical destination. Used for `ignore`. * - `mcpJson` — parse a JSON MCP servers file and write canonical * `mcp.json`. */ type ImportFeatureMode = 'singleFile' | 'directory' | 'flatFile' | 'mcpJson'; type ContentNormalizer = (content: string, sourceFile: string, destinationFile: string) => string; interface ImportEntryContext { readonly absolutePath: string; readonly relativePath: string; readonly content: string; readonly destDir: string; readonly normalizeTo: (destinationFile: string) => string; } interface ImportEntryMapping { readonly destPath: string; readonly toPath: string; readonly content: string; } type ImportEntryMapper = (ctx: ImportEntryContext) => Promise | ImportEntryMapping | null; /** Optional declarative frontmatter post-processing for the default mappers. */ type FrontmatterRemap = (frontmatter: Record) => Record; interface ImportFeatureSpec { readonly feature: ImportFeatureKind; readonly mode: ImportFeatureMode; readonly source: ImportSourcePaths; /** Tried after `source` in the same scope when the primary chain finds nothing (singleFile only). */ readonly fallbacks?: ImportSourcePaths; /** Canonical destination directory under the project root (e.g. `.agentsmesh/rules`). */ readonly canonicalDir: string; /** For `singleFile` only: the destination filename inside `canonicalDir`. */ readonly canonicalRootFilename?: string; /** For `directory` mode: file extensions to match (`['.md']`, `['.mdc']`, …). */ readonly extensions?: readonly string[]; /** For `directory` mode: pick a built-in mapper. */ readonly preset?: 'rule' | 'command' | 'agent'; /** Optional frontmatter post-processing applied by built-in mappers. */ readonly frontmatterRemap?: FrontmatterRemap; /** Custom mapper. Wins over `preset` when both are set. */ readonly map?: ImportEntryMapper; /** For `singleFile` rules: marks the imported entry as a root rule (`root: true`). */ readonly markAsRoot?: boolean; /** For `flatFile` and `mcpJson`: canonical destination filename. */ readonly canonicalFilename?: string; /** * For `mcpJson` mode: the top-level JSON key holding the server map in the * source file. Defaults to `mcpServers`. VS Code / Copilot use `servers`. */ readonly mcpServersKey?: string; } interface TargetImporterDescriptor { readonly rules?: ImportFeatureSpec | readonly ImportFeatureSpec[]; readonly commands?: ImportFeatureSpec; readonly agents?: ImportFeatureSpec; readonly skills?: ImportFeatureSpec; readonly mcp?: ImportFeatureSpec; readonly hooks?: ImportFeatureSpec; readonly permissions?: ImportFeatureSpec; readonly ignore?: ImportFeatureSpec; } /** Declared output families for reference rewriting and decoration (architecture P1-3). */ interface TargetOutputFamily { readonly id: string; readonly kind: 'primary' | 'mirror' | 'additional'; /** Match generated paths under this prefix (e.g. Copilot `.github/instructions/`). */ readonly pathPrefix?: string; /** Explicit paths for additional root mirrors (Cursor, Gemini compat). */ readonly explicitPaths?: readonly string[]; } interface ExtraRuleOutputContext { readonly refs: ReadonlyMap; readonly scope: TargetLayoutScope; } type ExtraRuleOutputResolver = (rule: CanonicalFiles['rules'][number], context: ExtraRuleOutputContext) => readonly string[]; /** * Path resolvers for the output reference map. * Each method returns a relative output path, or null to skip. * * Shared pre-checks (root rule handling, target filtering) remain * centralized in map-targets.ts — descriptors only handle the * target-specific path logic after those guards pass. */ interface TargetPathResolvers { /** * Output path for a non-root, non-filtered rule, or `null` to suppress * generation. Targets whose capability `rules === 'none'` for a given * scope MUST return `null` so callers can drop the row rather than emit * to a fabricated directory path. */ rulePath(slug: string, rule: CanonicalRule): string | null; /** Output path for a command. Null suppresses generation. */ commandPath(name: string, config: ValidatedConfig): string | null; /** Output path for an agent. Null suppresses generation. */ agentPath(name: string, config: ValidatedConfig): string | null; } interface TargetManagedOutputs { dirs: readonly string[]; files: readonly string[]; } interface TargetLayout { /** Primary root instruction artifact for this scope, if any. */ readonly rootInstructionPath?: string; /** Output families for rewrite cache keys and root decoration (see `layout-outputs.ts`). */ readonly outputFamilies?: readonly TargetOutputFamily[]; /** Additional generated rule paths that share source ownership for reference rewriting. */ readonly extraRuleOutputPaths?: ExtraRuleOutputResolver; /** Optional renderer for scope-specific primary root instruction content. */ readonly renderPrimaryRootInstruction?: (canonical: CanonicalFiles) => string; /** Target-native skills directory for this scope, if any. */ readonly skillDir?: string; /** Files/directories agentsmesh fully manages for stale cleanup. */ readonly managedOutputs?: TargetManagedOutputs; /** Optional path rewriter for scope-specific generated outputs. Return null to skip emission. */ readonly rewriteGeneratedPath?: (path: string) => string | null; /** * Optional mirror hook. Called after rewriteGeneratedPath resolves the primary path. * Returns an additional path to emit the same content to, or null to skip mirroring. */ readonly mirrorGlobalPath?: (path: string, activeTargets: readonly string[]) => string | readonly string[] | null; /** Path resolvers for this scope. */ readonly paths: TargetPathResolvers; } type TargetLayoutScope = 'project' | 'global'; /** Scope extras hook (e.g. Claude Code global output-styles). */ type ScopeExtrasFn = (canonical: CanonicalFiles, projectRoot: string, scope: TargetLayoutScope, enabledFeatures: ReadonlySet) => Promise; /** Single block for global-mode support (replaces scattered global* fields). */ interface GlobalTargetSupport { readonly capabilities: TargetCapabilities; readonly detectionPaths: readonly string[]; readonly layout: TargetLayout; readonly scopeExtras?: ScopeExtrasFn; } /** Import-path builder: populates refs with (target path -> canonical path) mappings. */ type ImportPathBuilder = (refs: Map, projectRoot: string, scope?: TargetLayoutScope) => Promise; /** Rule linter function signature. */ type RuleLinter = (canonical: CanonicalFiles, projectRoot: string, projectFiles: string[], options?: { scope?: TargetLayoutScope; }) => LintDiagnostic[]; /** Feature-specific lint hook signature. */ type FeatureLinter = (canonical: CanonicalFiles, options?: unknown) => LintDiagnostic[]; type GeneratedOutputMerger = (existing: string | null, pending: GenerateResult | undefined, newContent: string, resolvedPath: string) => string | null; /** Optional per-feature lint hooks for target-specific validation. */ interface TargetLintHooks { readonly commands?: FeatureLinter; readonly mcp?: FeatureLinter; readonly permissions?: FeatureLinter; readonly hooks?: FeatureLinter; readonly ignore?: FeatureLinter; readonly settings?: FeatureLinter; } /** High-level category for grouping/filtering in docs and UI. */ type TargetCategory = 'cli' | 'ide' | 'agent-platform'; /** * User-facing metadata for a target. Drives display names, docs, and links in * README/website, replacing hardcoded enumerations. */ interface TargetMetadata { /** Human-readable display name, e.g. "Claude Code". */ readonly displayName: string; /** High-level category for filtering. */ readonly category: TargetCategory; /** Official tool homepage or canonical documentation URL. */ readonly officialUrl: string; /** One-line description used in tool lists and tables. */ readonly shortDescription: string; } /** * How a native-install pick rule derives canonical entity names from the files * found under its directory. * - `basename`: recursively collect files ending in `suffix`; name = basename * minus `suffix` (e.g. `.md`, `.mdc`). * - `skillDir`: skill tree — `{name}/SKILL.md` plus flat top-level `*.md`. * - `firstSegment`: the single segment after the rule prefix is the name * (e.g. `.claude/skills/{name}/...`). */ type NativePickStrategy = { readonly kind: 'basename'; readonly suffix: string; } | { readonly kind: 'skillDir'; } | { readonly kind: 'firstSegment'; }; /** Maps a native directory prefix to a canonical feature + name strategy. */ interface NativePickRule { /** POSIX path prefix under the repo root; matches the dir or any subpath. */ readonly prefix: string; /** Canonical feature the matched files contribute to. */ readonly feature: 'commands' | 'rules' | 'agents' | 'skills'; /** How to derive entity names from the matched directory. */ readonly strategy: NativePickStrategy; } /** Frontmatter-dialect hint for `.mdc` flat-file target inference. */ interface NativeDialectHint { /** Frontmatter key whose presence identifies this target. */ readonly frontmatterKey: string; } /** * Descriptor-driven data for the install subsystem's native-path inference. * Replaces the per-target `if (target === '…')` ladders (arch §3.1): each * target declares its own pick paths / dialect hints instead. */ interface NativeInstallSupport { /** Ordered pick-path rules; the first matching prefix wins. */ readonly pickPaths?: readonly NativePickRule[]; /** * Escape hatch for irreducibly custom inference (e.g. Gemini's `:`-namespaced * command names, Copilot's overlapping `.github/*` dirs). When present it * fully owns inference for this target and `pickPaths` is ignored. */ readonly inferPick?: (repoRoot: string, posixPath: string) => Promise; /** Frontmatter-dialect hints for `.mdc` flat-file target inference. */ readonly dialectHints?: readonly NativeDialectHint[]; } /** * Full self-describing target descriptor. * Bundles everything needed to generate, import, lint, and detect a target. */ interface TargetDescriptor { /** * Unique target identifier, e.g. 'claude-code'. The `string & {}` widening * keeps plugin ids assignable while still letting `BuiltinTargetId` literal * checks (`if (id === 'claude-code')`) get autocomplete + typo protection * in editor tooling. Runtime validation lives in * `target-descriptor.schema.ts` (`/^[a-z][a-z0-9-]*$/`). */ readonly id: BuiltinTargetId | (string & {}); /** User-facing metadata (display name, category, URL, description) */ readonly metadata: TargetMetadata; /** Feature generators (rules, commands, agents, etc.) */ readonly generators: TargetGenerators; /** Feature support levels */ readonly capabilities: TargetCapabilities; /** Consolidated global-mode metadata. */ readonly globalSupport?: GlobalTargetSupport; /** Message shown when import finds nothing for this target */ readonly emptyImportMessage: string; /** Optional linter for canonical files */ readonly lintRules: RuleLinter | null; /** Optional per-feature lint hooks */ readonly lint?: TargetLintHooks; /** Project-scope target layout metadata */ readonly project: TargetLayout; /** * Declares which embedded-capability features support user-configured conversion. * When the corresponding conversion is disabled in config, the feature generator is skipped. */ readonly supportsConversion?: { readonly commands?: true; readonly agents?: true; }; /** * Optional descriptor-driven importer block. When present, the shared * `runDescriptorImport` orchestrator handles scan + map for each declared * feature (with scope variance expressed as data, eliminating * `if (scope === 'global')` branches in importer bodies). Targets with * irreducibly custom parsing keep `generators.importFrom` and may delegate * declarable parts of their flow to the runner. */ readonly importer?: TargetImporterDescriptor; /** Import reference map builder */ readonly buildImportPaths: ImportPathBuilder; /** Filesystem paths used to detect this target during `init` */ readonly detectionPaths: readonly string[]; /** * Declares which shared artifact paths this target owns or consumes. * Used by the reference rewriter to select the correct artifact map for shared outputs. * Example: codex-cli owns '.agents/skills/', copilot consumes it in global mode. */ readonly sharedArtifacts?: { readonly [pathPrefix: string]: 'owner' | 'consumer'; }; /** * Descriptor-driven native-install inference data (extends.pick from native * files, `.mdc` dialect hints). Consumed by `src/install/native` and * `src/install/manual` so those modules carry no target-id literals. */ readonly nativeInstall?: NativeInstallSupport; /** * Optional native settings sidecar (e.g. Gemini `.gemini/settings.json` when embedded features are on). * * `enabledFeatures` is the active feature set for this generate run. Emitters * MUST gate every settings key on its corresponding feature (mcpServers -> * `mcp`, hooks -> `hooks`, agents -> `agents`, permissions -> `permissions`, * ignore-derived keys -> `ignore`) so a disabled feature never leaks into the * sidecar. */ readonly emitScopedSettings?: (canonical: CanonicalFiles, scope: TargetLayoutScope, enabledFeatures: ReadonlySet) => readonly { readonly path: string; readonly content: string; }[]; /** Optional target-specific merge strategy for generated outputs. */ readonly mergeGeneratedOutputContent?: GeneratedOutputMerger; /** * Async post-pass for hook generator outputs (e.g. Copilot hook script assets under `.github/hooks/`). */ readonly postProcessHookOutputs?: (projectRoot: string, canonical: CanonicalFiles, outputs: readonly { readonly path: string; readonly content: string; }[]) => Promise; /** * When true, the target preserves manual-only activation semantics (e.g. * Cursor's `alwaysApply: false` without globs/description). Targets without * this flag get a lint warning when canonical rules have `trigger: 'manual'`. */ readonly preservesManualActivation?: boolean; /** * When true, `agentsmesh init` excludes this target from the default bulk * starter scaffold. Used by codex-cli because its `AGENTS.md` index format * collides with other AGENTS.md-first targets when multiple targets are * scaffolded together. Explicit `--target codex-cli` still works. */ readonly excludeFromStarterInit?: boolean; /** * Built-in default values for `commands_to_skills` / `agents_to_skills` * conversion projections. A `true` value enables conversion by default; an * explicit `false` disables it (still consults the user's per-target config * override before honoring this default). When the field is `undefined`, * `shouldConvert{Commands,Agents}ToSkills` falls back to the caller-supplied * `defaultEnabled` argument (used by plugin targets that haven't declared * a default). */ readonly conversionDefaults?: { readonly commandsToSkills?: boolean; readonly agentsToSkills?: boolean; }; } export type { ContentNormalizer as C, ExtraRuleOutputContext as E, FeatureLinter as F, GenerateResult as G, ImportPathBuilder as I, LintDiagnostic as L, RuleLinter as R, ScopeExtrasFn as S, TargetCapabilities as T, ExtraRuleOutputResolver as a, GeneratedOutputMerger as b, GlobalTargetSupport as c, ImportResult as d, TargetDescriptor as e, TargetGenerators as f, TargetLayout as g, TargetLayoutScope as h, TargetLintHooks as i, TargetManagedOutputs as j, TargetOutputFamily as k, TargetPathResolvers as l };