一键导入
codex-support
Multi-target output system — target abstraction, backend routing, content transforms for Codex CLI and future targets
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Multi-target output system — target abstraction, backend routing, content transforms for Codex CLI and future targets
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when modifying imports, creating new files, refactoring modules, or understanding how components relate. Not needed for simple single-file edits.
LLM-powered injection of project context into installed agent templates via `aspens customize agents`
Core conventions, tech stack, and project structure for aspens
Claude/Codex CLI execution layer — prompt loading, stream-json parsing, file output extraction, path sanitization, skill file writing, and skill rule generation
Top-level Commander wiring, welcome screen, missing-hook warning, CliError exit handling, and the public programmatic API surface
Context health analysis — freshness, domain coverage, hub surfacing, drift detection, LLM-powered interpretation, and auto-repair for generated agent context
| name | codex-support |
| description | Multi-target output system — target abstraction, backend routing, content transforms for Codex CLI and future targets |
| triggers | {"files":["src/lib/target.js","src/lib/target-transform.js","src/lib/backend.js","AGENTS.md",".aspens.json"],"keywords":["codex","target","backend","AGENTS.md",".aspens.json","sanitize","transform","multi-target","parity"]} |
You are working on multi-target output support — the system that lets aspens generate documentation for Claude Code, Codex CLI, or both simultaneously.
.claude/skills/, codex → .agents/skills/ + directory-scoped AGENTS.md). Backend = which LLM CLI generates the content (claude -p or codex exec).TARGETS.claude (centralized) and TARGETS.codex (directory-scoped). Each defines paths and capability flags: supportsHooks, supportsSettings, supportsGraph, supportsSkills, needsActivationSection, needsCodeMapEmbed, supportsMCP. Codex also has maxInstructionsBytes (32 KiB) and userSkillsDir. Codex's needsCodeMapEmbed is false — condensed cluster/framework data goes into the synthetic .agents/skills/architecture/ skill instead of the root AGENTS.md.CANONICAL_VARS (hardcoded Claude paths from doc-init.js). Transforms run after generation to produce other target formats.transformForTarget() remaps paths and content. For Codex: base skill → root AGENTS.md, domain skills → both .agents/skills/{domain}/SKILL.md and source directory AGENTS.md. generateCodexSkillReferences() creates .agents/skills/architecture/ with code-map data.collectSkillsForList() (internal) reads every skill from disk under sourceTarget.skillsDir and overlays pending in-flight changes (files passed to the transform) so the root instructions file's ## Skills section always lists every on-disk skill — not just the subset that changed in this sync. Pending changes win for descriptions; on-disk content survives for unchanged skills.transformToDirectoryScoped loads instructionsFile from disk via repoPath context parameter when it's not in the canonical files array (e.g., during doc init --strategy skip-existing or incremental doc sync). Uses a single readFileSync from fs wrapped in try/catch (no separate existsSync check).sanitizeCodexInstructions() and sanitizeCodexSkill() strip Claude-specific references (hooks, skill-rules.json, Claude Code mentions) from Codex output.sanitizePublishedContent(content, filePath) — Single-chokepoint sanitizer invoked by skill-writer.js on every disk write. Always strips ## Activation blocks and ## Key Files blocks. Outside code-map.md, also strips count-bearing blocks: **Hub files…**, **Domain clusters:**, **High-churn hotspots:**, **Framework entry points…**. Defense in depth — upstream leaks can't reach the user.syncSkillsSection() removes LLM-emitted Skill-section variants (## Skills Reference, ## Skills Overview, etc.) before injecting the canonical ## Skills list. Doc-init and doc-sync prompts also forbid such headings.ensureRootKeyFilesSection(content, graphSerialized) — Post-processes root instructions file to guarantee a ## Key Files section with top hub files from the graph.mergeConfiguredTargets(existing, next) — Merges target arrays to avoid dropping previously configured targets during narrower runs. Validates against TARGETS keys, deduplicates.getAllowedPaths(targets) — Returns { dirPrefixes, exactFiles } union across all active targets.detectAvailableBackends() checks if claude and codex CLIs are installed. resolveBackend() picks best match: explicit flag > target match > fallback..aspens.json at repo root stores { targets, backend, version, saveTokens? }. readConfig() returns null if missing or if the config is structurally invalid. isValidConfig() validates targets, backend, version, and saveTokens (via isValidSaveTokensConfig()).loadConfig(repoPath, { persist }) — Reads .aspens.json and, if missing, recovers via inferConfig() from on-disk artifacts. Returns { config, recovered }. Persists inferred config to disk by default unless persist: false is passed.saveTokens): Optional object in .aspens.json validated by isValidSaveTokensConfig() — checks enabled (boolean), warnAtTokens/compactAtTokens (positive integers, compact > warn unless either is MAX_SAFE_INTEGER), saveHandoff/sessionRotation (booleans), optional claude/codex sub-objects with enabled and mode.writeConfig preserves feature config: writeConfig() reads existing config and merges — saveTokens preserved unless explicitly set to null (intentional removal) or undefined (keep existing). Targets and backend also merge with existing.doc-sync uses publishFilesForTargets() to generate output for all configured targets from a single LLM run. repoPath is passed through to the transform context.inferConfig() only adds 'codex' to inferred targets when .codex/ config dir or .agents/skills/ dir exists.buildCodexSkillRefs() only includes the architecture skill reference when a graph was actually serialized.architecture skill is generated from graph data and has no Claude counterpart by design. logicalKeyForFile() returns null for codex architecture paths so assertTargetParity() won't raise a parity violation for the missing Claude side.CANONICAL_VARS.writeSkillFiles() handles direct-write files. writeTransformedFiles() handles directory-scoped AGENTS.md with an explicit path allowlist and warn-and-skip policy. Both writers run their payloads through sanitizePublishedContent before touching disk.validateTransformedFiles() rejects absolute paths, traversal, and unexpected filenames. writeTransformedFiles() enforces the same checks.add agent/command/hook and customize agents throw CliError for Codex-only repos. add skill works for both targets.persistGraphArtifacts() returns data without writing files when target.supportsGraph === false. Hook installation skipped when supportsHooks === false.readConfig() treats malformed but parseable JSON (e.g., wrong types for targets/backend/version/saveTokens) as invalid and returns null, same as missing config.repoPath context is required for disk fallback — callers of transformForTarget must pass repoPath in the context object for instructionsFile to load from disk when not in canonical files, and for collectSkillsForList to enumerate on-disk skills.src/lib/target.js for all target property definitionsLast Updated: 2026-05-11