When Anthropic's `enabled_artifacts_attachments` conversation setting
is false, Claude creates files via the skills-runner `create_file` MCP
tool instead of the legacy `artifacts` tool. The display_content shape
is identical (json_block with language / code / filename), only the
tool_use.name differs. The v1.9.1 strict allowlist was rejecting it,
silently dropping every artifact in those conversations.
Allowlist now accepts both 'artifacts' and 'create_file'. Other skills
tools that happen to share json_block display (view, list_directory,
etc.) stay filtered out by name.
Two regression tests added:
- positive: create_file with markdown json_block extracts correctly
- negative: view tool with similar json_block stays filtered
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tidy the repo root: package.json moves to src/tests/ (still tracked) so the
Vitest harness lives next to the tests it runs. package-lock.json is now
untracked (matches CLAUDE.md's stated intent) -- gitignored at the new path.
node_modules/ moved alongside (still gitignored).
Run npm test from src/tests/ now (not src/). CLAUDE.md Testing section
updated.
Add vitest coverage for the documented model ID shapes (dateless 4.6+,
dated pre-4.6, convenience aliases) across all three known families,
plus regression for the \d{1,2} minor boundary, unknown-family
fallthrough (using a hypothetical claude-mythos-* as the example), and
a sanity check that every DEFAULT_MODEL_TIMELINE entry parses cleanly
through formatModelName.
Drop a comment above formatModelName linking to Anthropic's official
model-ids docs so future maintainers know which shapes are supposed to
be supported.
52 tests passing (was 36).
Move DEFAULT_MODEL_TIMELINE, inferModel, formatModelName, and getModelBadgeClass
from browse.js (and the duplicates from content.js) into utils.js. Adds 19 tests
covering the regex regression from v1.9.1, timeline boundaries, and edge cases.
Side fixes baked in:
- content.js had drifted timeline values, including 2025-02-29 (not a leap year;
JS silently rolled it to March 1). Now uses the canonical browse.js values.
- getModelBadgeClass now guards against null/undefined input instead of throwing.