AI-powered adeno-associated virus (AAV) vector design for gene therapy including capsid engineering, promoter selection, and tropism optimization.
日本語の概要は準備中です。原文の説明を表示しています。
JavaScript/TypeScript ES2024+, async/await, DOM manipulation, Node.js, and API integration. Use when writing vanilla JS/TS code, working with REST/fetch APIs, implementing frontend logic, or configuring JS build tools.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Optimized for ECMAScript 2024+, Node.js 22+, TypeScript 5.5+, and modern browser or server-first JavaScript runtimes.
Expert guidance for writing modern JavaScript code with ES2024+ features, async programming patterns, DOM manipulation, API integration, and best practices following official JavaScript resources at https://developer.mozilla.org/en-US/docs/Web/JavaScript.
Before claiming "skill applied successfully":
// Before
async function loadProfile() {
const response = await fetch('/api/profile');
return response.json();
}
// After
export async function loadProfile(signal) {
const response = await fetch('/api/profile', { signal });
if (!response.ok) {
throw new Error(`Profile request failed: ${response.status}`);
}
return response.json();
}
Adds cancellation and explicit response validation so network failures do not masquerade as parsing bugs.
Use symptom -> action triggers: when one matches, apply this skill and verify with the protocol below.
Core JavaScript Development:
Asynchronous Programming:
Data Handling:
API Integration:
// Logical Assignment Operators (ES2021)
const obj = { a: 1 };
obj.a ??= 10; // Only assign if obj.a is null/undefined
console.log(obj.a); // 1 (no change)
obj.b ??= 20; // Assign if missing
console.log(obj.b); // 20
// Numeric Separators (ES2021)
const billion = 1_000_000_000;
const bytes = 0xff_13_ff; // Hex
// String methods (ES2022)
const str = "Hello World";
console.log(str.replaceAll('l', 'L')); // "HeLLo WorLd"
console.log(str.at(-1)); // "d" (last character)
// Array methods (ES2023)
const array = [1, 2, 3, 4, 5];
console.log(array.toReversed()); // [5, 4, 3, 2, 1]
console.log(array.toSorted()); // [1, 2, 3, 4, 5]
console.log(array.with(2, 99)); // [1, 2, 99, 4, 5] (non-mutating)
// Hashbang (for scripts)
#!/usr/bin/env node
console.log("Executable script!");
// Object.groupBy (ES2024)
const people = [
{ name: "Alice", age: 25, role: "admin" },
{ name: "Bob", age: 30, role: "user" },
{ name: "Charlie", age: 25, role: "user" },
];
const groupedByAge = Object.groupBy(people, ({ age }) => age);
console.log(groupedByAge);
// { 25: [{name: "Alice", age: 25, role: "admin"}, ...], 30: [...] }
const groupedByRole = Map.groupBy(people, ({ role }) => role);
console.log(groupedByRole);
// Map { "admin" => [...], "user" => [...] }
// Template literals with expressions
const firstName = "John";
const lastName = "Doe";
const greeting = `Hello, ${firstName} ${lastName}!`;
// Tagged template for custom formatting
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<strong>${values[i]}</strong>` : '');
}, '');
}
const message = highlight`User ${firstName} is online.`;
// "User <strong>John</strong> is online."
// Object destructuring
const user = { id: 1, name: "Alice", email: "alice@example.com", role: "admin" };
const { name, email, role: userRole } = user;
console.log(name, email, userRole); // "Alice", "alice@example.com", "admin"
// Array destructuring
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first, second, rest); // 1, 2, [3, 4, 5]
// Destructuring in function parameters
function processRecipe({ title, difficulty, ingredients = [] }) {
return `${title} (${difficulty}) - ${ingredients.length} ingredients`;
}
const recipe = { title: "Pasta", difficulty: "Medium", ingredients: ["Pasta", "Sauce"] };
processRecipe(recipe); // "Pasta (Medium) - 2 ingredients"
// Basic async/await
async function fetchUser(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const user = await response.json();
return user;
} catch (error) {
console.error("Failed to fetch user:", error);
throw error;
}
}
// Parallel async operations with Promise.all
async function fetchRecipeData(recipeId) {
try {
const [recipe, reviews, ingredients] = await Promise.all([
fetch(`/api/recipes/${recipeId}`).then(r => r.json()),
fetch(`/api/recipes/${recipeId}/reviews`).then(r => r.json()),
fetch(`/api/recipes/${recipeId}/ingredients`).then(r => r.json()),
]);
return { recipe, reviews, ingredients };
} catch (error) {
console.error("Failed to fetch recipe data:", error);
throw error;
}
}
// Race with Promise.any (ES2021)
async function fetchFromMultipleEndpoints() {
const endpoints = [
'/api/v1/users',
'/api/v2/users',
'/api/v3/users',
];
try {
const response = await Promise.any(
endpoints.map(url => fetch(url).then(r => r.json()))
);
return response;
} catch (error) {
// All promises rejected
console.error("All endpoints failed:", error);
throw error;
}
}
// All Settled (ES2020)
async function fetchWithStatus() {
const requests = [
fetch('/api/users'),
fetch('/api/recipes'),
fetch('/api/stats'),
];
const results = await Promise.allSettled(requests);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} successful`);
} else {
console.error(`Request ${index} failed:`, result.reason);
}
});
}
// Async generator function
async function* fetchPaginatedUsers(pageSize = 10) {
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await fetch(`/api/users?page=${page}&limit=${pageSize}`);
const { users, totalPages } = await response.json();
yield* users;
page++;
hasMore = page <= totalPages;
// Add delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 500));
}
}
// Using async iterator
async function getAllUsers() {
const userIterator = fetchPaginatedUsers();
const allUsers = [];
for await (const user of userIterator) {
allUsers.push(user);
console.log(`Fetched: ${user.name}`);
}
return allUsers;
}
// In ES modules, you can use await at top level
const config = await fetch('/api/config').then(r => r.json());
console.log('App config loaded:', config);
// This is useful for modules that need to load data before export
export const recipes = await fetch('/api/recipes').then(r => r.json());
export const users = await fetch('/api/users').then(r => r.json());
// Basic GET request
async function getRecipes(filters = {}) {
const queryParams = new URLSearchParams(filters);
const url = `/api/recipes?${queryParams}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return await response.json();
}
// POST request with JSON body
async function createRecipe(recipeData) {
const response = await fetch('/api/recipes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(recipeData),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to create recipe');
}
return await response.json();
}
// PUT request with authentication
async function updateRecipe(recipeId, recipeData, token) {
const response = await fetch(`/api/recipes/${recipeId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify(recipeData),
});
if (!response.status === 200 && response.status !== 204) {
throw new Error(`Update failed: ${response.status}`);
}
return await response.json();
}
// DELETE request
async function deleteRecipe(recipeId, token) {
const response = await fetch(`/api/recipes/${recipeId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error(`Delete failed: ${response.status}`);
}
return true;
}
import axios from 'axios';
// Create axios instance with default config
const api = axios.create({
baseURL: '/api',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Request interceptor for adding authentication
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor for error handling
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Unauthorized - redirect to login
localStorage.removeItem('token');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
// API methods
export const recipesApi = {
async getAll(filters = {}) {
const response = await api.get('/recipes', { params: filters });
return response.data;
},
async getById(recipeId) {
const response = await api.get(`/recipes/${recipeId}`);
return response.data;
},
async create(recipeData) {
const response = await api.post('/recipes', recipeData);
return response.data;
},
async update(recipeId, recipeData) {
const response = await api.put(`/recipes/${recipeId}`, recipeData);
return response.data;
},
async delete(recipeId) {
const response = await api.delete(`/recipes/${recipeId}`);
return response.data;
},
};
// Retry utility with exponential backoff
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
} catch (error) {
lastError = error;
console.log(`Attempt ${attempt + 1} failed, retrying...`);
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw new Error(`Failed after ${maxRetries} attempts: ${lastError.message}`);
}
// Usage with error handling
async function getRecipeWithRetry(recipeId) {
try {
const recipe = await fetchWithRetry(`/api/recipes/${recipeId}`);
console.log('Recipe loaded:', recipe);
return recipe;
} catch (error) {
console.error('Failed to load recipe:', error);
// Show user-friendly error message
return { error: true, message: 'Failed to load recipe. Please try again.' };
}
}
// Modern element selection
const button = document.querySelector('#submit-btn');
const items = document.querySelectorAll('.list-item');
const container = document.getElementById('container');
const firstChild = document.querySelector('.item:first-child');
// Using closest for event delegation
document.addEventListener('click', (event) => {
const button = event.target.closest('.action-button');
if (button) {
console.log('Button clicked:', button.dataset.id);
}
});
// Element creation and manipulation
function addRecipeToList(recipe) {
const li = document.createElement('li');
li.className = 'recipe-item';
li.dataset.recipeId = recipe.id;
li.innerHTML = `
<h3>${recipe.title}</h3>
<p>${recipe.description}</p>
<button class="delete-btn">Delete</button>
`;
// Add event listener to delete button
const deleteBtn = li.querySelector('.delete-btn');
deleteBtn.addEventListener('click', () => deleteRecipe(recipe.id));
// Append to container
document.getElementById('recipe-list').appendChild(li);
}
// Element removal
function removeRecipeElement(recipeId) {
const element = document.querySelector(`[data-recipe-id="${recipeId}"]`);
if (element) {
element.remove();
}
}
// Form submission with validation
const form = document.getElementById('recipe-form');
form.addEventListener('submit', async (event) => {
event.preventDefault(); // Prevent default form submission
const formData = new FormData(form);
const recipeData = {
title: formData.get('title'),
description: formData.get('description'),
category: formData.get('category'),
difficulty: formData.get('difficulty'),
};
// Validation
if (!recipeData.title || recipeData.title.length < 3) {
showError('Title is required and must be at least 3 characters');
return;
}
try {
// Submit to API
const response = await fetch('/api/recipes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(recipeData),
});
if (response.ok) {
showSuccess('Recipe created successfully!');
form.reset();
}
} catch (error) {
showError('Failed to create recipe: ' + error.message);
}
});
// Debounce for search input
let searchTimeout;
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', (event) => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const query = event.target.value;
if (query.length >= 2) {
performSearch(query);
}
}, 300); // Wait 300ms after user stops typing
});
// Intersection Observer for infinite scroll
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadMoreRecipes();
}
});
}, {
root: null,
threshold: 0.1,
});
// Observe sentinel element
const sentinel = document.getElementById('load-more-sentinel');
observer.observe(sentinel);
// map - Transform array
const recipes = [
{ title: 'Pasta', difficulty: 'Medium' },
{ title: 'Salad', difficulty: 'Easy' },
];
const titles = recipes.map(recipe => recipe.title);
// ['Pasta', 'Salad']
// filter - Select elements
const easyRecipes = recipes.filter(recipe => recipe.difficulty === 'Easy');
// [{ title: 'Salad', difficulty: 'Easy' }]
// reduce - Aggregate array
const wordCount = recipes.reduce((count, recipe) => {
return count + recipe.title.split(' ').length;
}, 0);
// find - Find first matching element
const pasta = recipes.find(recipe => recipe.title.includes('Pasta'));
// some - Check if any matches
const hasMediumDifficulty = recipes.some(recipe => recipe.difficulty === 'Medium'); // true
// every - Check if all match
const allHaveTitles = recipes.every(recipe => recipe.title.length > 0); // true
// sort - Sort array
const sortedRecipes = [...recipes].sort((a, b) =>
a.title.localeCompare(b.title)
);
// flatMap - Map and flatten
const nested = [[1, 2], [3, 4]];
const flattened = nested.flatMap(arr => arr); // [1, 2, 3, 4]
// Object.keys, Object.values, Object.entries
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
role: 'admin',
};
const keys = Object.keys(user); // ['id', 'name', 'email', 'role']
const values = Object.values(user); // [1, 'Alice', 'alice@example.com', 'admin']
const entries = Object.entries(user);
// [['id', 1], ['name', 'Alice'], ['email', 'alice@example.com'], ['role', 'admin']]
// Object.fromEntries - Convert back to object
const filtered = Object.fromEntries(
Object.entries(user).filter(([key]) => key !== 'role')
);
// { id: 1, name: 'Alice', email: 'alice@example.com' }
// Object.freeze - Make immutable
const config = Object.freeze({ apiUrl: '/api/v1' });
config.apiUrl = '/api/v2'; // Error in strict mode
// Set - Unique values
const tags = new Set(['Easy', 'Medium', 'Medium', 'Hard']);
console.log(tags.size); // 3
tags.add('Easy');
console.log(tags.has('Medium')); // true
tags.delete('Hard');
const uniqueTags = Array.from(tags); // ['Easy', 'Medium']
// Map - Key-value pairs with any type
const userRoles = new Map();
userRoles.set(1, 'admin');
userRoles.set(2, 'user');
userRoles.set('alice', 'editor');
console.log(userRoles.get(1)); // 'admin'
console.log(userRoles.has('alice')); // true
const roles = Array.from(userRoles.entries());
// [[1, 'admin'], [2, 'user'], ['alice', 'editor']]
// Creating dates
const now = new Date();
const specificDate = new Date('2024-02-01');
const fromTimestamp = new Date(17068896000000);
// Date formatting
function formatDate(date) {
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
};
return new Intl.DateTimeFormat('en-US', options).format(date);
}
// "February 1, 2024 at 12:00 PM"
// Relative time (e.g., "2 hours ago")
function getRelativeTime(date) {
const now = new Date();
const diff = now - date;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (seconds < 60) return 'just now';
if (minutes < 60) return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
if (hours < 24) return `${hours} hour${hours > 1 ? 's' : ''} ago`;
return `${days} day${days > 1 ? 's' : ''} ago`;
}
// Date manipulation
function addDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
function isSameDay(date1, date2) {
return date1.toDateString() === date2.toDateString();
}
class StorageManager {
static set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('Failed to save to localStorage:', error);
}
}
static get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('Failed to read from localStorage:', error);
return defaultValue;
}
}
static remove(key) {
try {
localStorage.removeItem(key);
} catch (error) {
console.error('Failed to remove from localStorage:', error);
}
}
static clear() {
try {
localStorage.clear();
} catch (error) {
console.error('Failed to clear localStorage:', error);
}
}
static has(key) {
return localStorage.getItem(key) !== null;
}
}
class StateManager {
constructor(initialState = {}) {
this.state = initialState;
this.listeners = [];
}
setState(newState) {
this.state = { ...this.state, ...newState };
this.notify();
}
subscribe(listener) {
this.listeners.push(listener);
listener(this.state);
}
notify() {
this.listeners.forEach(listener => listener(this.state));
}
}
// Usage
const stateManager = new StateManager({
user: null,
recipes: [],
loading: false,
});
stateManager.subscribe((state) => {
console.log('State updated:', state);
// Update UI
});
stateManager.setState({ recipes: [...] });
// Debounce
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Throttle
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// Random ID
function generateId() {
return Math.random().toString(36).substr(2, 9);
}
// Slugify text
function slugify(text) {
return text
.toString()
.toLowerCase()
.trim()
.replace(/\s+/g, '-')
.replace(/[^\w\-]+/g, '');
}
// Format number with commas
function formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// Truncate text
function truncate(text, maxLength) {
return text.length > maxLength
? text.substring(0, maxLength - 3) + '...'
: text;
}
const and let instead of var'use strict')export default async function ProfileCard({ userId }) {
const user = await getUser(userId);
return <section>{user.name}</section>;
}
import { ErrorBoundary } from 'react-error-boundary';
<ErrorBoundary fallbackRender={() => <p>Something went wrong.</p>}>
<ProfileDashboard />
</ErrorBoundary>
import { axe } from 'jest-axe';
test('search form has no obvious accessibility violations', async () => {
const { container } = render(<SearchForm />);
expect(await axe(container)).toHaveNoViolations();
});
This skill is written to stay usable across GitHub Copilot, Claude Code, and Codex.
$CODEX_HOME/skills/javascript-development and restart Codex after major changes.Preferred MCP Server: None required
SKILL.md, bundled references or scripts, and manual verification. Show the exact commands, evidence, and final checks you used before concluding."まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
AI-powered adeno-associated virus (AAV) vector design for gene therapy including capsid engineering, promoter selection, and tropism optimization.
日本語の概要は準備中です。原文の説明を表示しています。
Improve the clarity and voice of AI-assisted academic writing (papers, theses, rebuttals) and
日本語の概要は準備中です。原文の説明を表示しています。
12-agent academic paper writing pipeline. 11 modes (full/plan/outline/revision/revision-coach/abstract/lit-review/format-convert/citation-check/disclosure/rebuttal-audit). 6 paper types, 5 citation formats, bilingual abstracts, LaTeX/DOCX-via-Pandoc/PDF output. Style Calibration + Writing Quality Check + Anti-Patterns with IRON RULE markers. Triggers: write paper, academic paper, guide my paper, parse reviews, audit my rebuttal, check my response draft, AI disclosure, 寫論文, 學術論文, 引導我寫論文, 審查意見, 評估回覆, 논문 작성, 초록 작성, 논문 수정, 논문 계획을 도와줘, 심사 의견 반영, 답변서 점검, AI 사용 고지.
日本語の概要は準備中です。原文の説明を表示しています。
Systematic writing framework for philosophy and interdisciplinary academic papers from optimized outline to submission-ready manuscript. Use when users want to: (1) write a paper from a detailed outline, (2) ensure quality control during writing, (3) maintain consistency across chapters, (4) prepare a submission-ready manuscript, or (5) systematically execute a planned paper. Triggered by phrases like 'write the paper from this outline,' 'compose the full manuscript,' 'execute the outline,' or when users have completed strategic planning (academic-paper-strategist skill) and are ready to write. Takes optimized outline as input; outputs complete manuscript with iterative quality checks.
日本語の概要は準備中です。原文の説明を表示しています。
Multi-perspective academic paper review with dynamic reviewer personas. Runs a 5-seat, role-separated review panel (Journal-Fit Reviewer + 3 peer-review roles + Devil's Advocate) with field-specific expertise; role separation is not a claim of independent error processes. Supports full review, re-review (verification), quick assessment, methodology focus, Socratic guided, and calibration modes. Triggers on: review paper, peer review, manuscript review, referee report, review my paper, critique paper, simulate review, editorial review, calibrate reviewer, reviewer calibration, measure reviewer accuracy, 審查論文, 論文審查, 模擬審查, 同儕審查, 幫我審這篇, 以審查人角度評估, 審查者校準, 논문 심사, 동료 심사, 모의 심사, 심사자 관점에서 평가, 심사자 보정.
日本語の概要は準備中です。原文の説明を表示しています。
Systematic strategic planning framework for philosophy and interdisciplinary academic papers targeting preprint platforms (PhilArchive, arXiv, PhilSci-Archive). Use when users want to: (1) plan a paper on a specific topic, (2) identify research gaps and assess originality, (3) develop optimized paper outlines, (4) prepare for preprint submission, or (5) understand platform requirements and writing standards. Triggered by phrases like 'plan a paper on,' 'help me design a paper about,' 'identify research gaps in,' 'is this idea original,' or when users need structured research planning. The skill guides through three phases: Platform Analysis (identifying target venue and studying sample papers), Theoretical Framework (AI-driven literature search and gap identification), and Outline Optimization (structured design with reviewer-perspective self-assessment). Each phase includes quality evaluation standards and validation checkpoints.
日本語の概要は準備中です。原文の説明を表示しています。