Install any skill in seconds. Free to start, no credit card required.
Get Started Free →codeck entry point. Scans local files for materials, shows pipeline dashboard with diagnostic intelligence, guides user to the next step.
SkillScore83/100
Test results 73 · Live runs 93
3/3 safety checks passed
32%73%of test cases passed +41 pts
Passed 16 of 22 test cases with the skill, and 7 of 22 without it.
10 fixed6 passed either way5 still failing1 broke
One test taskThe user asks to revise bullet points on slide 2 to highlight quarterly revenue growth. Which file must be modified as the primary content source of truth, and which file should NOT be edited directly?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add hiyeshu-codeck
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install hiyeshu-codeckThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/hiyeshu-codeck/SKILL.md https://app.decimal.ai/s/hiyeshu-codeck/SKILL.md.claude/skills/hiyeshu-codeck/SKILL.mdThis gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add hiyeshu-codeckimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add hiyeshu-codeckfrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add hiyeshu-codeckimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add hiyeshu-codeckimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add hiyeshu-codeckfrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add hiyeshu-codeckfrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 5 other files are not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add hiyeshu-codeckimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add hiyeshu-codeckfrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add hiyeshu-codeckfrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add hiyeshu-codeckimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 5 other files are not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add hiyeshu-codeckimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 5 other files are not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add hiyeshu-codeckfrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("hiyeshu-codeck")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/hiyeshu-codeck/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/hiyeshu-codeck/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add hiyeshu-codeckNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/hiyeshu-codeck/SKILL.md https://app.decimal.ai/s/hiyeshu-codeck/SKILL.md.agents/skills/hiyeshu-codeck/SKILL.mdThis gets SKILL.md only. The skill's 5 other files are not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 5 other files are not included.
Raw files: /s/hiyeshu-codeck/SKILL.md · /s/hiyeshu-codeck.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/hiyeshu-codeck/SKILL.mdcurl -fsSL https://app.decimal.ai/s/hiyeshu-codeck.jsonThis gets SKILL.md only. The skill's 5 other files are not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
Open the deck room, scan materials, diagnose project state, route work to role lanes, and write the role channel as work moves.
Flag anomalies proactively: stale stages, upstream changes not reflected downstream, unresolved threads, and tasks without a handoff.
codeck follows a slock-style collaboration model in one skill runtime.
A skill is a channel: an addressable role with a clear write boundary, durable
room files, and a handoff protocol. /codeck is the entry channel. The
sub-skills are internal channels that own one part of the room.
Fixed role lanes:
| Handle | Owns | Writes |
|---|---|---|
@orchestrator | room state, routing, task tickets, threads, handoffs | MEMORY.md, tasks/tasks.md, threads/threads.md, channel/YYYY-MM-DD.md, roles/*.md |
@outline | narrative, deck content, slide structure | deck.md |
@design | design skeleton, visual system, HTML source | DESIGN.md, custom.css, slides.html |
@review | audience resistance, QA, scoped fixes | review.md, scoped fixes to slides.html / custom.css |
@speech | talk track, presenter notes | speech.md, HTML data-notes |
@export | PDF/PPTX output and export QA | PDF/PPTX files, export notes in review.md or MEMORY.md |
Dynamic role persona:
diagnosis.md for the recommended person behind @outline, @design, and @review.@outline may work with Feynman's instinct; @design may use Ravel's formal logic.Default user-facing output is compact: judgment, artifact, next action. The expanded role channel is written to channel/YYYY-MM-DD.md; show it only when the user asks to see the channel.
Compact response shape:
codeck: {state}
I read this as {task}. I {did/will do} {action}.
Artifact: `{path}`
Next: `{next command or next lane}`
When the user asks to see the channel, show the handoff:
@orchestrator
I read the current request as: {task}. Owner: @outline.
@outline
I will change `deck.md` first and leave visual files alone.
@design
I will rebuild `slides.html` and `custom.css` after the content changes.
@review
I will check whether the change lands for the target audience.
Room documents are not equal. The room has one current truth layer, one work-state layer, and one audit layer.
| Layer | Files | Read rule | Write rule |
|---|---|---|---|
| Current truth | MEMORY.md, deck.md, DESIGN.md, custom.css, slides.html, latest assembled HTML, speech.md when present | Read first. These files define the rebuildable deck. | Rewrite compactly so they describe the current room, not the whole history. |
| Work state | diagnosis.md, tasks/tasks.md, threads/threads.md, roles/*.md, review.md | Read current material diagnosis, active tickets, open decisions, lane persona/rules, and the latest valid review. | Keep live coordination clear; mark old decisions answered/defaulted/superseded. |
| Audit trail | channel/YYYY-MM-DD.md, legacy PROJECT.md, legacy outline.md, legacy design-notes.md, superseded review notes, generated old previews | Read only when debugging history or when the user asks to see the channel. | Append-only or leave untouched. Never use as generation truth. |
Read order for every lane:
MEMORY.md Active Context, Role Registry, Open Threads, Task Index, Artifacts, Assumed Defaults, Decision Log.tasks/tasks.md open or active rows only.threads/threads.md open rows and their detail blocks only; closed rows are audit evidence.diagnosis.md for material interpretation and dynamic persona, when present.roles/{lane}.md for current lane persona and lane-local rules.deck.md; DESIGN.md before custom.css / slides.html; assembled HTML only after build-html.sh.channel/YYYY-MM-DD.md only for audit/debug. Channel text must not override current truth.Legacy artifacts:
outline.md is audit-only if found from an older room. Do not read, write, or recreate it during normal generation.design-notes.md is a legacy design scratchpad from main. Do not recreate it; migrate useful facts into DESIGN.md, roles/design.md, or latest valid review.md.review.md is the latest QA report only when it matches the current assembled HTML. If HTML changed after review, treat review as stale.*-rN.html or *-deck.css files are historical unless they were produced by the current build-html.sh path.MEMORY.md is the deck room index and current-state map. It replaces PROJECT.md.
Keep it short. Store current decisions, state, and indexes. Do not paste the full deck, channel transcript, or stale preview history.
MEMORY.md must include:
# Memory
## Active Context
- Current request:
- Active lane:
- Next:
- Blockers:
## Room Truth Contract
- Current truth: MEMORY.md, deck.md, DESIGN.md, custom.css, slides.html, latest assembled HTML, speech.md when present.
- Work state: diagnosis.md current material reading, tasks/tasks.md active tickets, threads/threads.md open decisions and decision ledger, roles/*.md lane memory, latest valid review.md.
- Audit only: channel/YYYY-MM-DD.md, legacy PROJECT.md, legacy outline.md, legacy design-notes.md, superseded reviews, old previews, project-root sibling CSS.
- Rule: audit text never overrides current truth; legacy outline.md is never a generation source.
## Role Registry
| Handle | Dynamic persona | Owns | Writes |
|--------|-----------------|------|--------|
| @orchestrator | codeck room lead | room state, routing, handoffs | MEMORY.md, tasks, threads, channel, roles |
| @outline | {from diagnosis.md or fallback} | narrative and deck content | deck.md |
| @design | {from diagnosis.md or fallback} | design skeleton, visual system, HTML source | DESIGN.md, custom.css, slides.html |
| @review | {from diagnosis.md or fallback} | audience resistance and QA | review.md, scoped source fixes |
| @speech | {coach if needed} | speech script and presenter notes | speech.md, HTML data-notes |
| @export | publisher | PDF/PPTX output and QA | PDF/PPTX, export notes |
## Latest Channel Summary
{short summary of the latest role exchange}
## Open Threads
| ID | Kind | Owner | Status | Blocking | Writes To | Decision |
|----|------|-------|--------|----------|-----------|----------|
## Task Index
| Task | Owner | Status | Artifact | Handoff |
|------|-------|--------|----------|---------|
## Artifacts
- Diagnosis:
- Content source:
- Design source:
- Current preview:
- Latest review:
- Speech:
- Final exports:
## Assumed Defaults
- {field}: {value} — {reason}
## Decision Log
| Time | ID | Moment | Resolution | Source |
|------|----|--------|------------|--------|
Workspace directories:
$DECK_DIR/MEMORY.md
$DECK_DIR/channel/YYYY-MM-DD.md
$DECK_DIR/tasks/tasks.md
$DECK_DIR/threads/threads.md
$DECK_DIR/roles/orchestrator.md
$DECK_DIR/roles/outline.md
$DECK_DIR/roles/design.md
$DECK_DIR/roles/review.md
$DECK_DIR/roles/speech.md
$DECK_DIR/roles/export.md
channel/YYYY-MM-DD.md stores expanded role turns. Append one block per handoff:
Channel is an audit trail. Do not read it during normal generation, and do not let old channel facts override MEMORY.md, deck.md, or DESIGN.md.
## {ISO time} — {request}
@orchestrator
{routing read}
@{owner}
{claim and action}
@{next-owner}
{handoff if any}
tasks/tasks.md stores live claim tickets. Do not use hard locks. Each ticket has owner, status, artifact, and handoff. Closed history belongs in MEMORY.md summaries or channel, not as a growing task backlog.
threads/threads.md stores unresolved decisions, content conflicts, design disputes, cross-owner proposals, and the Decision Ask ledger. A user-facing question is never free-floating; it must first exist here as a decision record. Once resolved, copy the outcome into the owned source and MEMORY.md Decision Log, then mark the thread answered/defaulted/superseded. Normal reads treat only open rows as work state.
For Decision Ask entries, keep an index row and a short detail block:
| D-20260511-01 | Decision Ask: Deck Intent | @outline | open | true | deck.md, MEMORY.md | choose audience scene/duration package |
### D-20260511-01 — Deck Intent
- Reason:
- Current read:
- Recommendation:
- Options:
- A:
- B:
- C:
- Default:
- Runtime:
roles/*.md stores each fixed lane's long-lived rules plus current dynamic persona. Update it when diagnosis.md changes.
Legacy migration:
MEMORY.md is missing but PROJECT.md exists, read PROJECT.md as legacy memory.MEMORY.md and copy intent/defaults/AskUser or Decision Log entries into the matching sections.PROJECT.md untouched. Do not keep writing to it.Decision Ask is a room-scoped decision layer, not a questionnaire. AskUser UI is only one possible renderer.
The room is the durable scope. A necessary ask belongs to $DECK_DIR/threads/threads.md first, then renders through the runtime:
Decision Ask semantics -> AskUser UI if available -> plain text pause if blocking -> assumed default if non-blocking
Default rule:
Infer what materials already prove.
Use a reasonable default when the risk is low.
Ask only when the answer changes the deck direction.
One /codeck run may use at most 2 Decision Ask rounds. Count all internal modules against that budget.
Allowed Decision Ask moments:
MEMORY.md, or deck.md. Do not ask for slide count directly; derive it from duration: 15 minutes ≈ 10 pages, 30 minutes ≈ 20 pages, 45 minutes ≈ 25-30 pages.Never create a Decision Ask for:
Those steps are automatic.
Decision record shape:
id: D-YYYYMMDD-NN
owner: @orchestrator | @outline | @design | @export | @speech | @review
moment: Project Init | Deck Intent | Design Direction | Export Format | Speech Style | User-Owned Conflict
reason: why this cannot be safely inferred
current_read: what the room already knows
recommendation: the preferred option and one concrete reason
options: 2-3 mutually exclusive packages
default: the option to use if non-blocking or unanswered
blocking: true only when inventing the answer would damage the deck direction or user commitment
writes_to: MEMORY.md | deck.md | DESIGN.md | speech.md | review.md | export artifact
status: open | answered | defaulted | superseded
Every rendered ask must contain:
Suggest [X] because [reason].Only state verified facts. Unexecuted actions use "will / plan to".
Runtime rendering:
blocking: true, show the same decision as a compact plain-text question, write it to threads/threads.md, and stop before mutating the target artifact.blocking: false, use the default, record assumed default, and continue.threads/threads.md and stop.If the user does not answer a non-blocking decision, use the recommended option. Record it in MEMORY.md as assumed default.
Persist every Decision Ask result:
threads/threads.md stores every open decision before it is rendered to the user.MEMORY.md stores current room state, project-level intent, defaults, Decision Log, task index, thread index, and artifact index. It is not a transcript.deck.md stores deck-shaping decisions that affect rebuilds.Automatic light review must not trigger Decision Ask. Write findings and fixes to review.md. Ask only when the content has a real conflict the user must decide.
/codeck routes the user's request before running the pipeline:
| User intent | Action | Decision Ask |
|---|---|---|
| New / continue deck | @orchestrator opens room → scan → diagnose → @outline → @design → @review | Deck Intent and Design Direction only if needed, max 2 rounds |
| "make slide 3 less dense" / concrete content edit | @outline edits deck.md → @design rebuilds → @review checks | none |
| "change visual style" / "change style" | @design runs Design Direction, updates DESIGN.md, rebuilds → @review checks | Design Direction |
| "export" | @export exports latest HTML | Export Format only if PDF / PPTX / all is missing |
| "export PDF" / "export PPTX" | @export exports requested format | none |
| "create speech script" | @speech generates speech.md and syncs notes | Speech Style only if style or duration is missing |
For edits, deck.md is the single truth source. HTML is the audience preview, not the editing surface.
Before a lane works:
@orchestrator writes or updates a task ticket.threads/threads.md as proposals.After a lane works:
MEMORY.md Active Context, Latest Channel Summary, Open Threads, Task Index, Artifacts, Assumed Defaults, and Decision Log so they describe current state..) — the user's project. Materials live here. Final HTML goes here too so the user can open it directly.$DECK_DIR — codeck's deck room. MEMORY.md, channel/, tasks/, threads/, roles/, deck.md, diagnosis.md, DESIGN.md, custom.css, slides.html, review.md, speech.md.Scan materials in .. Write intermediate artifacts to $DECK_DIR. Output final HTML to ..
DECK_DIR="$HOME/.codeck/projects/$(basename "$(pwd)")"
CODECK_SKILL_DIR="${CODECK_SKILL_DIR:-}"
if [ -z "$CODECK_SKILL_DIR" ]; then
for d in \
"${CLAUDE_PLUGIN_ROOT}/skills/codeck" \
"$HOME"/.claude/plugins/cache/*/codeck/*/skills/codeck \
"$HOME"/.codex/plugins/cache/*/codeck/*/skills/codeck \
"$HOME/.agents/skills/codeck" \
"$HOME/.codex/skills/codeck" \
"$HOME/.claude/skills/codeck"; do
if [ -d "$d/scripts" ]; then CODECK_SKILL_DIR="$d"; break; fi
done
fi
[ -n "$CODECK_SKILL_DIR" ] || { echo "codeck skill scripts not found; set CODECK_SKILL_DIR" >&2; exit 1; }
. "$CODECK_SKILL_DIR/scripts/resolve-dirs.sh"
mkdir -p "$DECK_DIR"
mkdir -p "$DECK_DIR/channel" "$DECK_DIR/tasks" "$DECK_DIR/threads" "$DECK_DIR/roles"
bash "$CODECK_SKILL_DIR/scripts/init-room.sh" "$DECK_DIR"
bash "$CODECK_SKILL_DIR/scripts/status.sh" "$DECK_DIR"
Initialize the room before creating any Decision Ask:
$DECK_DIR/MEMORY.md is missing, create it from the Memory protocol template.$DECK_DIR/PROJECT.md exists, migrate its intent, defaults, and AskUser / Decision Log entries into MEMORY.md.$DECK_DIR/tasks/tasks.md is missing, create it with the task ticket table.$DECK_DIR/threads/threads.md is missing, create it with the thread table.roles/*.md file is missing, create it with that fixed lane's ownership and write boundaries.Read existing MEMORY.md, active tasks/tasks.md rows, open threads/threads.md rows, and deck.md before creating any Decision Ask. Ignore legacy outline.md. If a value is already stated there or safely inferable from materials, do not ask it again.
Track Decision Ask rounds for this run. Stop at 2. If another non-blocking decision remains, use the recommended default and write it to MEMORY.md. If a blocking decision remains, leave it open in threads/threads.md and stop before touching its target artifact.
Scan the current directory (the user's project), not DECK_DIR.
bash "$CODECK_SKILL_DIR/scripts/scan-materials.sh" .
Do not use eval find for material scan. If the script is unavailable, use a plain find with explicit ! -path exclusions.
If materials exist and $DECK_DIR/diagnosis.md doesn't, read materials and diagnose:
If the material involves a domain you're unfamiliar with, or uses specialized terminology, search the web first. Understand the field's key concepts, common presentation patterns, and what experts in this space consider hard to explain. This grounds your diagnosis in real knowledge, not guesses.
Examples:
Don't pick from a list. Don't match by domain. Find the person whose way of thinking cracks this specific problem.
Outline role — who asks the right question about this material? Identify the core tension in the material, then find someone known for penetrating that type of tension — regardless of their field. A product launch where the real challenge is "why should anyone care" might need Sondheim (every lyric earns its place) more than a marketing guru. A technical architecture talk where the challenge is "too many moving parts" might need Tufte (information compression) or a film editor (what to cut).
Test: does this person's way of questioning change what the outline includes and excludes? If the outline would be the same without them, the match is wrong.
Design role — whose formal logic mirrors the content's structure? Not "good designer" but "whose way of organizing form matches how this argument moves." A content that builds layer by layer might map to Ravel. A content driven by contrast might map to Caravaggio. A content that strips away to reveal essence might map to Dieter Rams. The match can come from any domain — music, painting, architecture, choreography — because form is transferable.
Test: can you state the structural mapping in one sentence? ("This content does X; this person's work does X in visual/sonic/spatial form.") If not, the match is decorative.
Review role — inverse selection. Not the expert. The listener most likely to struggle or push back. The role determines what gets flagged — not correctness, but comprehension and trust.
Test: would this person interrupt you mid-presentation? If not, pick someone harder to convince.
One-line summary per file: what it is, how it can be used. Written into diagnosis.md.
$DECK_DIR/diagnosis.md# Diagnosis
## Materials
| File | Content | Use for |
|------|---------|---------|
| {filename} | {one-line description} | {role in deck} |
## Domain
{description}
## Expression challenge
{hardest part to convey}
## Audience starting point
{what they know / don't know}
## Role recommendations
### Outline stage
{role name} — {derivation: domain + why this person's method of explaining reshapes the structure}
### Design stage
{role name} — {derivation: expression challenge + structural mapping between content and this person's visual logic}
### Review stage
{role name} — {derivation: audience starting point + why this person would struggle or push back}
Skip diagnosis if no materials — let user provide topic directly in each stage.
Define what the user sees in each pipeline state. These are the exact outputs — not summaries.
When Phase 2 finds zero files:
No materials found in this directory.
That's fine — you can start from a topic directly.
Tell me the topic in one sentence, or drop files here and run /codeck again.
Warm, not clinical. One primary action. No error language.
When build-html.sh or assemble.sh exits non-zero:
Assembly failed: {error message}
Check that custom.css and slides.html exist in {DECK_DIR}.
Run /codeck to rebuild.
Name the exact file missing. Give the exact command to fix it.
When status.sh detects staleness:
⚠ {stage} is stale — {upstream file} changed after {downstream file} was built.
Run /codeck to rebuild.
One line. Name the files. Give the command.
status.sh already outputs the dashboard. Below it, add:
threads/threads.md, only if any are openDon't redraw the table.
This is the first moment the user sees the system think. Don't dump three role names — tell a story in three beats:
What your content is really about — the core tension, in one sentence. Not the topic, the underlying struggle. ("Your material isn't about microservices — it's about convincing a team to accept short-term pain for long-term sanity.")
Who I'm bringing in, and why — the derivation, not just the name. Connect the person's way of thinking to the content's tension. ("For the outline, I'm thinking of Feynman — not because this is physics, but because your argument needs to make the invisible feel obvious. He did that better than anyone.")
What this changes — one concrete consequence. ("This means the outline won't start with background. It'll start with the one thing your audience already knows is broken.")
Keep it short. Three paragraphs, not three pages. The point is: the user should feel their content was seen, not just processed.
Every /codeck run writes the role channel to channel/YYYY-MM-DD.md. User responses stay compact by default. If the user asks for the channel, show the role blocks for the work just done or about to happen.
Channel output is evidence, not authority. If channel conflicts with MEMORY.md, deck.md, or DESIGN.md, trust the current-truth file and record a thread only when the conflict changes the deck.
Use handles, not stage names:
@orchestrator
{what I read, which task ticket I opened, who owns it}
@outline
{what I will change or changed, and which artifact I touched}
@design
{handoff or rebuild note}
@review
{verification lens and result}
Do not invent work. If a role did not participate, omit it.
All outputs go to $DECK_DIR/. Next skill reads upstream outputs.
Before the response ends, update:
MEMORY.md Active Context, Latest Channel Summary, Task Index, Artifactstasks/tasks.md current ticket status and handoffthreads/threads.md if a decision remainschannel/YYYY-MM-DD.md with the expanded role exchangestatus.sh prints a NEXT recommendation. Use it:
| NEXT | Suggest |
|---|---|
outline | "Materials scanned. Next: /codeck will plan the structure." |
design | "Outline ready. Next: /codeck will generate slides." |
review | "Slides generated. Next: /codeck will inspect and fix." |
export / speech | "Review done. Next: /codeck export PDF or /codeck speech script." |
User can run /codeck anytime to see progress.
Automatically, when a task matches. Use when the user says "codeck", "new deck", "make a presentation", "make a deck", "new slides", "build a presentation", "export", "speech", "script", or wants to start or continue a presentation project. /codeck is the user-facing entry; legacy sub-skills are internal modules.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.