Skip to content

feat: add takt as a target tool (map rulesync features to TAKT facets)#1539

Merged
dyoshikawa merged 2 commits intomainfrom
takt
Apr 22, 2026
Merged

feat: add takt as a target tool (map rulesync features to TAKT facets)#1539
dyoshikawa merged 2 commits intomainfrom
takt

Conversation

@dyoshikawa
Copy link
Copy Markdown
Owner

Summary

Add a new target tool takt to rulesync so that rulesync source files (rules, subagents, commands, skills) are generated into the TAKT faceted-prompting directories under .takt/facets/ (project) and ~/.takt/facets/ (global).

Feature mapping

rulesync feature Default facet directory Allowed takt.facet overrides
subagents personas/ persona only
rules policies/ policy, knowledge, output-contract
commands instructions/ instruction only
skills instructions/ instruction, knowledge, output-contract

Highlights

  • Always emit plain Markdown (frontmatter dropped); preserve source filename stem.
  • Optional takt.name lets users rename the emitted stem to escape collisions; validated against path-traversal characters.
  • Cross-feature collision detection in .takt/facets/instructions/ between commands and skills: log a warning naming both sources and skip writes without aborting the rest of the run.
  • Project + global scopes both supported.
  • gitignore registry covers .takt/{runs,tasks,.cache}/ and shared facet directories under both commands/skills and rules/skills.
  • README.md, docs/reference/{supported-tools,file-formats}.md, and new docs/tools/takt.md kept in sync.
  • Happy-path e2e cases for every (takt × feature) cell in both project and global modes plus a dedicated collision e2e.

Out of scope (permanently)

  • Workflow YAML (.takt/workflows/*.yaml), config.yaml, runtime state (tasks/, runs/), repertoire packaging.
  • rulesync import for TAKT skill files: throws an explicit "Importing existing TAKT facet files into rulesync is not supported" because frontmatter is dropped on generate (lossy by design).

Closes #1536

Test plan

  • pnpm cicheck passes (5155 unit + 201 file + content checks)
  • pnpm dev generate --targets takt produces files under .takt/facets/{personas,policies,instructions,knowledge,output-contracts}/
  • Happy-path e2e cases for each (takt × feature) cell in project mode
  • Happy-path e2e cases for each (takt × feature) cell in global mode
  • Cross-feature collision e2e: same stem in commands + skills emits warning and skips writes; non-colliding files still emitted
  • Path-traversal guard on takt.name and TaktSkill.getDirPath

🤖 Generated with Claude Code

- Map rulesync features to TAKT facet directories:
  - subagents -> personas/, rules -> policies/ (default),
    commands -> instructions/, skills -> instructions/ (default)
- Optional takt.facet frontmatter routes rules to knowledge/output-contracts
  and skills to knowledge/output-contracts; unknown values raise validation errors
- Always emit plain Markdown (frontmatter dropped); preserve source filename stem
- Optional takt.name allows renaming the emitted stem to escape collisions
  (validated against path-traversal characters)
- Detect cross-feature collisions in .takt/facets/instructions/ between
  commands and skills: log a warning naming both sources and skip writes
  without aborting the run
- Support both project (.takt/facets/) and global (~/.takt/facets/) scopes
- Update gitignore registry to cover .takt/{runs,tasks,.cache}/ and
  facet directories shared across features
- Sync README, docs/reference/{supported-tools,file-formats}.md, and
  add docs/tools/takt.md
- Add happy-path e2e cases for every (takt x feature) cell in both
  project and global modes plus a dedicated collision e2e

Closes #1536

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 22, 2026 05:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new takt tool target, generating Rulesync sources into TAKT’s faceted-prompting directory structure under .takt/facets/ (and ~/.takt/facets/ in global mode), including facet routing via takt.facet, optional renaming via takt.name, and collision handling for shared instruction facets.

Changes:

  • Register takt as a tool target across processors, schemas, docs, and spelling config.
  • Implement TAKT generators for rules/commands/subagents/skills + shared TAKT helpers and tests.
  • Add TAKT-specific collision detection between commands and skills writing into .takt/facets/instructions/, plus e2e coverage and gitignore registry entries.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/types/tool-targets.ts Adds takt to supported tool targets list.
src/types/tool-targets.test.ts Updates tool targets snapshot/expectations.
src/lib/generate.ts Adds TAKT command/skill collision pre-scan and filtering hooks in generation flow.
src/features/takt-shared.ts Introduces shared TAKT validation/utilities (takt.name safety, takt.facet resolution).
src/features/takt-shared.test.ts Unit tests for TAKT shared helpers.
src/features/subagents/takt-subagent.ts Implements TAKT subagent emission to .takt/facets/personas/*.md.
src/features/subagents/takt-subagent.test.ts Unit tests for TAKT subagent behavior.
src/features/subagents/subagents-processor.ts Registers takt subagent factory/metadata.
src/features/subagents/subagents-processor.test.ts Updates supported-target expectations to include takt.
src/features/skills/takt-skill.ts Implements TAKT skills emission as flat facet files (instructions/knowledge/output-contracts).
src/features/skills/takt-skill.test.ts Unit tests for TAKT skill mapping and guards.
src/features/skills/skills-processor.ts Registers takt skill factory/metadata.
src/features/skills/skills-processor.test.ts Updates supported-target expectations to include takt.
src/features/skills/rulesync-skill.ts Adds optional takt frontmatter keys to Rulesync skill schema/types.
src/features/rules/takt-rule.ts Implements TAKT rules emission into facet dirs with takt.facet + takt.name.
src/features/rules/takt-rule.test.ts Unit tests for TAKT rule mapping and validation.
src/features/rules/rulesync-rule.ts Adds optional takt frontmatter keys to Rulesync rule schema.
src/features/rules/rules-processor.ts Registers takt rule factory/metadata.
src/features/rules/rules-processor.test.ts Updates supported-target expectations to include takt.
src/features/commands/takt-command.ts Implements TAKT command emission to .takt/facets/instructions/*.md.
src/features/commands/takt-command.test.ts Unit tests for TAKT command mapping and validation.
src/features/commands/commands-processor.ts Registers takt command factory/metadata.
src/features/commands/commands-processor.test.ts Updates supported-target expectations to include takt.
src/e2e/e2e-takt.spec.ts Adds e2e coverage for command/skill instruction-facet collision behavior.
src/e2e/e2e-subagents.spec.ts Adds TAKT to subagent e2e matrix (project + global).
src/e2e/e2e-skills.spec.ts Adds TAKT to skills e2e matrix (project + global).
src/e2e/e2e-rules.spec.ts Adds TAKT to rules e2e matrix (project + global).
src/e2e/e2e-commands.spec.ts Adds TAKT to commands e2e matrix (project + global).
src/cli/commands/gitignore-entries.ts Adds TAKT gitignore entries and dedupes exported entry list.
src/cli/commands/gitignore-entries.test.ts Adjusts tests for intentional cross-feature gitignore entry reuse + deduped export.
skills/rulesync/supported-tools.md Documents takt in supported tools matrix (skill docs sync source).
skills/rulesync/file-formats.md Documents takt frontmatter keys in file format reference (skill docs sync source).
docs/tools/takt.md Adds dedicated TAKT tool documentation page.
docs/reference/supported-tools.md Documents takt in supported tools matrix.
docs/reference/file-formats.md Documents takt frontmatter keys in file format reference.
cspell.json Adds TAKT-related spelling dictionary entries.
README.md Adds TAKT to the supported tools matrix.
Comments suppressed due to low confidence (1)

src/lib/generate.ts:566

  • For the takt target, skills are emitted as flat .md files under facet dirs, but this path still goes through processDirFeatureGeneration (directory-based). That means --delete cannot remove orphaned TAKT skill files (it only deletes directories), and collision filtering here may leave previously-generated colliding files on disk. Consider handling TAKT skills as file-based output (AiFile + writeAiFiles/removeOrphanAiFiles) or adding a TAKT-specific orphan-file cleanup pass that enumerates .takt/facets/{instructions,knowledge,output-contracts}/*.md and removes non-generated stems.

Comment on lines +121 to +143
/**
* Override: TAKT skills emit a single flat file under `relativeDirPath`,
* not a nested directory keyed by `dirName`. Drop `dirName` from the path.
*
* Preserves the same path-traversal guard as `AiDir.getDirPath` so a
* malicious `relativeDirPath` cannot escape `baseDir`.
*/
override getDirPath(): string {
const fullPath = join(this.baseDir, this.relativeDirPath);

const resolvedFull = resolve(fullPath);
const resolvedBase = resolve(this.baseDir);
const rel = relative(resolvedBase, resolvedFull);

if (rel.startsWith("..") || path.isAbsolute(rel)) {
throw new Error(
`Path traversal detected: Final path escapes baseDir. ` +
`baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}"`,
);
}

return fullPath;
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overriding getDirPath() to return the facet directory (dropping dirName) makes multiple TaktSkill instances share the same dirPath. This breaks the DirFeatureProcessor invariants: orphan cleanup can only delete directories (so old *.md facet files are never removed), and forDeletion() cannot represent deletable units. To support --delete and reliable diffs, TAKT skills likely need a file-based representation/processor (AiFile) or a custom delete implementation that operates on individual facet files rather than directories.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +99
static getSettablePaths({
global,
excludeToolDir,
}: {
global?: boolean;
excludeToolDir?: boolean;
} = {}): ToolRuleSettablePaths | ToolRuleSettablePathsGlobal {
if (global) {
return {
root: {
relativeDirPath: buildToolPath(
".takt",
join("facets", DEFAULT_TAKT_RULE_DIR),
excludeToolDir,
),
relativeFilePath: "overview.md",
},
};
}
return {
nonRoot: {
relativeDirPath: buildToolPath(
".takt",
join("facets", DEFAULT_TAKT_RULE_DIR),
excludeToolDir,
),
},
};
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getSettablePaths() only points rule discovery/deletion at .takt/facets/policies, but TAKT rules can also emit under .takt/facets/knowledge and .takt/facets/output-contracts via takt.facet. As a result, --delete and rulesync import won’t see those non-default facet files, leaving orphans when a rule changes facet. Consider setting nonRoot.relativeDirPath to .takt/facets (so the existing glob picks up all facets) and adjusting fromFile()/import mapping accordingly; also decide how root rule discovery should behave if a root rule uses a non-default facet.

Copilot uses AI. Check for mistakes.
Comment on lines +238 to +242
"takt",
{
class: TaktSkill,
meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: true },
},
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registering takt here implies the standard SkillsProcessor behaviors (directory discovery for import and directory-based orphan deletion). But TaktSkill emits flat facet files and TaktSkill.fromDir() throws, so rulesync import --targets takt --features skills will likely just report “No skill directories found” and skip rather than throwing the explicit “not supported” error described in the PR, and --delete won’t be able to remove orphan facet files. Consider special-casing takt skills in the import/generate pipelines (or introducing a file-based skills processor for takt) before advertising full skills support.

Copilot uses AI. Check for mistakes.
- Add takt: frontmatter block to RulesyncCommand and RulesyncSubagent
  schemas so takt.facet/takt.name typos are caught at parse time, matching
  the existing rule/skill schemas.
- TaktSkill.getRelativePathFromCwd now routes through toPosixPath so
  reported paths use forward slashes on Windows.
- Surface previously-swallowed conversion errors in the TAKT collision
  pre-pass via debug logging instead of silent catch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dyoshikawa dyoshikawa merged commit 5672e0a into main Apr 22, 2026
9 checks passed
@dyoshikawa dyoshikawa deleted the takt branch April 22, 2026 09:53
@dyoshikawa
Copy link
Copy Markdown
Owner Author

@dyoshikawa Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add takt as a target tool (map rulesync features to TAKT facets)

2 participants