mcpField
T
template-renderer

template-renderer

github.com/oimiragieo開発4466 回インストール17 週間前に更新
リポジトリ

template-renderer について

template-renderer は、仕様書・計画書・タスクのテンプレートを値で埋めるスキルです。Markdown 文書を生成するワークフロー向けに、トークン、パス、スキーマを検証します。

主な機能

  1. 01仕様書・計画書・タスクテンプレートのレンダリング
  2. 02{{TOKEN}} プレースホルダーの置換
  3. 03トークンの許可リストとサニタイズ
  4. 04テンプレートと出力パスの検証
  5. 05仕様書スキーマの検査
  6. 06不足・未使用トークンの通知

活用シーン

  1. 01収集した要件から仕様書を生成
  2. 02トークン値を使ったプロジェクト計画の作成
  3. 03検証済みテンプレートデータによるタスク文書の作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oimiragieo/agent-studio --skill template-renderer

インストール後、Claude Code で/template-rendererを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

commands/
template-renderer.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
template-renderer.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

詳細

テンプレートレンダラー

Template Renderer スキル - {{TOKEN}} プレースホルダーを実際の値に置き換えてテンプレートをレンダリングします。schema 検証とセキュリティ制御(SEC-SPEC-003、SEC-SPEC-004)により、specification-template.md、plan-template.md、tasks-template.md をサポートします。 - 3 種類すべてのテンプレートをレンダリング(仕様、計画、タスク) - {{TOKEN}} → 値の置換によるトークン置換 - セキュリティ:トークン値のサニタイズ(インジェクションを防止) - セキュリティ:トークンの許可リスト適用(事前定義されたトークンのみ許可) - セキュリティ:テンプレートパスの検証(PROJECT_ROOT のみ) - 仕様テンプレートのスキーマ検証 - 必須トークンが不足している場合のエラー処理 - 未使用トークンの警告システム - Markdown の書式と構造を保持
ステップ 1:入力の検証(セキュリティ - 必須)

テンプレートパスの検証(SEC-SPEC-002):

  • テンプレートファイルが PROJECT_ROOT 内に存在することを確認します
  • パストラバーサルの試み(../)を拒否します
  • .claude/templates/ 内のテンプレートのみを許可します

トークン許可リストの検証(SEC-SPEC-003):

// Allowed tokens by template type
const SPEC_TOKENS = [
  'FEATURE_NAME',
  'VERSION',
  'AUTHOR',
  'DATE',
  'STATUS',
  'ACCEPTANCE_CRITERIA_1',
  'ACCEPTANCE_CRITERIA_2',
  'ACCEPTANCE_CRITERIA_3',
  'TERM_1',
  'TERM_2',
  'TERM_3',
  'HTTP_METHOD',
  'ENDPOINT_PATH',
  'PROJECT_NAME',
];

const PLAN_TOKENS = [
  'PLAN_TITLE',
  'DATE',
  'FRAMEWORK_VERSION',
  'STATUS',
  'EXECUTIVE_SUMMARY',
  'TOTAL_TASKS',
  'FEATURES_COUNT',
  'ESTIMATED_TIME',
  'STRATEGY',
  'KEY_DELIVERABLES_LIST',
  'PHASE_N_NAME',
  'PHASE_N_PURPOSE',
  'PHASE_N_DURATION',
  'DEPENDENCIES',
  'PARALLEL_OK',
  'VERIFICATION_COMMANDS',
];

const TASKS_TOKENS = [
  'FEATURE_NAME',
  'VERSION',
  'AUTHOR',
  'DATE',
  'STATUS',
  'PRIORITY',
  'ESTIMATED_EFFORT',
  'RELATED_SPECS',
  'DEPENDENCIES',
  'FEATURE_DISPLAY_NAME',
  'FEATURE_DESCRIPTION',
  'BUSINESS_VALUE',
  'USER_IMPACT',
  'EPIC_NAME',
  'EPIC_GOAL',
  'SUCCESS_CRITERIA',
];

トークン値のサニタイズ(SEC-SPEC-004):

function sanitizeTokenValue(value) {
  return String(value)
    .replace(/[<>]/g, '') // Prevent HTML injection
    .replace(/\$\{/g, '') // Prevent template literal injection
    .replace(/\{\{/g, '') // Prevent nested token injection
    .trim();
}
ステップ 2:テンプレートの読み込み

Read または mcpfilesystemread_text_file を使用してテンプレートファイルを読み込みます:

  • .claude/templates/specification-template.md(46 個のトークン)
  • .claude/templates/plan-template.md(30 個以上のトークン)
  • .claude/templates/tasks-template.md(20 個以上のトークン)
ステップ 3:トークンの置換

すべての {{TOKEN}} プレースホルダーをサニタイズ済みの値に置き換えます:

function renderTemplate(templateContent, tokenMap) {
  let rendered = templateContent;

  // Replace each token
  for (const [token, value] of Object.entries(tokenMap)) {
    // Validate token is in whitelist
    if (!isAllowedToken(token, templateType)) {
      throw new Error(`Token not in whitelist: ${token}`);
    }

    // Sanitize value
    const sanitizedValue = sanitizeTokenValue(value);

    // Replace all occurrences
    const regex = new RegExp(`\\{\\{${token}\\}\\}`, 'g');
    rendered = rendered.replace(regex, sanitizedValue);
  }

  // Check for missing required tokens
  const missingTokens = rendered.match(/\{\{[A-Z_0-9]+\}\}/g);
  if (missingTokens) {
    throw new Error(`Missing required tokens: ${missingTokens.join(', ')}`);
  }

  return rendered;
}
ステップ 4:スキーマ検証(仕様テンプレートのみ)

仕様テンプレートの場合、レンダリングされた出力を JSON Schema に照らして検証します:

// Extract YAML frontmatter
const yamlMatch = rendered.match(/^---\n([\s\S]*?)\n---/);
if (!yamlMatch) {
  throw new Error('No YAML frontmatter found');
}

// Parse YAML
const yaml = require('js-yaml');
const frontmatter = yaml.load(yamlMatch[1]);

// Validate against schema
const schema = JSON.parse(
  fs.readFileSync('.claude/schemas/specification-template.schema.json', 'utf8')
);

const Ajv = require('ajv');
const ajv = new Ajv();
const validate = ajv.compile(schema);

if (!validate(frontmatter)) {
  throw new Error(`Schema validation failed: ${JSON.stringify(validate.errors)}`);
}
ステップ 5:出力の書き込み

Write または mcpfilesystemwrite_file を使用して、レンダリングされたテンプレートを出力パスに書き込みます:

  • 出力パスが PROJECT_ROOT 内にあることを確認します
  • 必要に応じて親ディレクトリを作成します
  • UTF-8 エンコーディングでファイルを書き込みます
ステップ 6:検証

レンダリング後のチェックを実行します:

# Check no unresolved tokens remain
grep "{{" <output-file> && echo "ERROR: Unresolved tokens found!" || echo "✓ All tokens resolved"

# For specifications: Validate YAML frontmatter
head -50 <output-file> | grep -E "^---$" | wc -l  # Should output: 2

# For specifications: Validate against schema (if ajv installed)
# ajv validate -s .claude/schemas/specification-template.schema.json -d <output-file>

</execution_process>

<best_practices>

  1. テンプレートパスは必ず検証する:読み込み前に PROJECT_ROOT 検証を使用します
  2. すべてのトークン値をサニタイズする:インジェクション攻撃を防止します(SEC-SPEC-004)
  3. トークンの許可リストを適用する:事前定義されたトークンのみを許可します(SEC-SPEC-003)
  4. トークン不足時はエラーにする:必須トークンの不足を黙って無視しないでください
  5. 未使用トークンを警告する:トークン名の誤入力に気づけるようにします
  6. Markdown の書式を保持する:インデント、箇条書き、コードブロックを変更しないでください
  7. 仕様のスキーマを検証する:仕様テンプレートに対して JSON Schema 検証を実行します
  8. すべての操作を記録する:テンプレート、使用したトークン、出力パスをメモリに記録します

</best_practices>

<error_handling>

必須トークンの不足:

ERROR: Missing required tokens in template:
  - {{FEATURE_NAME}}
  - {{ACCEPTANCE_CRITERIA_1}}

Provide these tokens in the token map.

無効なトークン(許可リストにない):

ERROR: Token not in whitelist: INVALID_TOKEN
Allowed tokens for specification-template: FEATURE_NAME, VERSION, AUTHOR, DATE, ...

テンプレートパスのトラバーサル:

ERROR: Template path outside PROJECT_ROOT
Path: ../../etc/passwd
Only templates from .claude/templates/ are allowed.

スキーマ検証の失敗(仕様テンプレート):

ERROR: Schema validation failed:
  - /version: must match pattern "^\d+\.\d+\.\d+$"
  - /acceptance_criteria: must have at least 1 item

未使用トークンの警告:

WARNING: Unused tokens provided:
  - EXTRA_TOKEN_1
  - EXTRA_TOKEN_2

These tokens are not in the template. Check for typos.

</error_handling>

**例 1:仕様テンプレートのレンダリング**
// From another skill (e.g., spec-gathering)
Skill({
  skill: 'template-renderer',
  args: {
    templateName: 'specification-template',
    outputPath: '.claude/context/artifacts/specifications/my-feature-spec.md',
    tokens: {
      FEATURE_NAME: 'User Authentication',
      VERSION: '1.0.0',
      AUTHOR: 'Claude',
      DATE: '2026-01-28',
      STATUS: 'draft',
      ACCEPTANCE_CRITERIA_1: 'User can log in with email and password',
      ACCEPTANCE_CRITERIA_2: 'Password meets complexity requirements',
      ACCEPTANCE_CRITERIA_3: 'Failed login attempts are logged',
    },
  },
});

例 2:計画テンプレートのレンダリング

Skill({
  skill: 'template-renderer',
  args: {
    templateName: 'plan-template',
    outputPath: '.claude/context/plans/my-feature-plan.md',
    tokens: {
      PLAN_TITLE: 'User Authentication Implementation Plan',
      DATE: '2026-01-28',
      FRAMEWORK_VERSION: 'Agent-Studio v3.1.0',
      STATUS: 'Phase 0 - Research',
      EXECUTIVE_SUMMARY: 'Implementation plan for JWT-based authentication...',
      TOTAL_TASKS: '14 atomic tasks',
      ESTIMATED_TIME: '2-3 weeks',
      STRATEGY: 'Foundation-first (schema) → Core features',
    },
  },
});

例 3:タスクテンプレートのレンダリング

Skill({
  skill: 'template-renderer',
  args: {
    templateName: 'tasks-template',
    outputPath: '.claude/context/artifacts/tasks/auth-tasks.md',
    tokens: {
      FEATURE_NAME: 'user-authentication',
      VERSION: '1.0.0',
      AUTHOR: 'Engineering Team',
      DATE: '2026-01-28',
      FEATURE_DISPLAY_NAME: 'User Authentication',
      FEATURE_DESCRIPTION: 'JWT-based authentication system',
      BUSINESS_VALUE: 'Enables user account management',
      USER_IMPACT: 'Users can securely access personalized features',
    },
  },
});

例 4:CLI の使用方法

# Using CLI wrapper (after implementation in main.cjs)
node .claude/skills/template-renderer/scripts/main.cjs \
  --template specification-template \
  --output ./my-spec.md \
  --tokens '{"FEATURE_NAME":"My Feature","VERSION":"1.0.0","AUTHOR":"Claude","DATE":"2026-01-28"}'

# Or with JSON file
node .claude/skills/template-renderer/scripts/main.cjs \
  --template plan-template \
  --output ./my-plan.md \
  --tokens-file ./tokens.json

例 5:spec-gathering との統合

// In spec-gathering skill (Task #16):
// After collecting requirements via progressive disclosure...

const tokens = {
  FEATURE_NAME: gatheredRequirements.featureName,
  VERSION: '1.0.0',
  AUTHOR: 'Claude',
  DATE: new Date().toISOString().split('T')[0],
  ACCEPTANCE_CRITERIA_1: gatheredRequirements.criteria[0],
  ACCEPTANCE_CRITERIA_2: gatheredRequirements.criteria[1],
  ACCEPTANCE_CRITERIA_3: gatheredRequirements.criteria[2],
  // ... more tokens
};

Skill({
  skill: 'template-renderer',
  args: {
    templateName: 'specification-template',
    outputPath: `.claude/context/artifacts/specifications/${featureName}-spec.md`,
    tokens: tokens,
  },
});

</usage_example>

メモリプロトコル(必須)

開始前:

cat .claude/context/memory/learnings.md

完了後:

  • 新しいパターン -> .claude/context/memory/learnings.md
  • 問題の発見 -> .claude/context/memory/issues.md
  • 決定事項 -> .claude/context/memory/decisions.md

中断を想定してください:コンテキストがリセットされる場合があります。メモリに記録されていなければ、実行されていないものとみなされます。

コメント