Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Choose, compile, launch, or run bounded AI-agent goals with explicit deliverables, proof rubrics, verifier gates, iteration caps, stop conditions, and approval boundaries. Includes a categorized Loop goals library for product, design, research, content, data, and operations plus advanced engineering loops for Codex, Claude Code, Cursor, and other SKILL.md-compatible agents.
SkillScore91/100
Test results 91
3/3 safety checks passed
50%91%of test cases passed +41 pts
Passed 20 of 22 test cases with the skill, and 11 of 22 without it.
9 fixed11 passed either way2 still failing0 broke
One test taskIf a scheduled time-based tick runs against a repository and the verifier command already succeeds on the initial check, what action should the runner take?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add fhajjej-ship-it-loop-it
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("fhajjej-ship-it-loop-it")
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 fhajjej-ship-it-loop-itThe 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/fhajjej-ship-it-loop-it/SKILL.md https://app.decimal.ai/s/fhajjej-ship-it-loop-it/SKILL.md.claude/skills/fhajjej-ship-it-loop-it/SKILL.mdThis gets SKILL.md only. The skill's 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itimport 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itfrom 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("fhajjej-ship-it-loop-it")
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/fhajjej-ship-it-loop-it/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/fhajjej-ship-it-loop-it/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 11 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 fhajjej-ship-it-loop-itNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/fhajjej-ship-it-loop-it/SKILL.md https://app.decimal.ai/s/fhajjej-ship-it-loop-it/SKILL.md.agents/skills/fhajjej-ship-it-loop-it/SKILL.mdThis gets SKILL.md only. The skill's 11 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 11 other files are not included.
Raw files: /s/fhajjej-ship-it-loop-it/SKILL.md · /s/fhajjej-ship-it-loop-it.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/fhajjej-ship-it-loop-it/SKILL.mdcurl -fsSL https://app.decimal.ai/s/fhajjej-ship-it-loop-it.jsonThis gets SKILL.md only. The skill's 11 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.
Turn an open-ended objective into a bounded run with a concrete artifact and proof. Loop It has two related libraries:
references/library/goals.json: the user-facing, categorized Loop goals library for product, design, research, content, data, and operations work.references/library/loops.json: advanced execution patterns for repository repair, verification, scheduling, and proactive routines.Loop goals describe the review-ready deliverable the user wants. Advanced loops describe how an engineering or operational task should iterate. Do not collapse these concepts or route a creative deliverable request into a repository repair loop.
Loop It's repository execution path is primarily for goal-based coding loops with an automated verifier. Its Loop goals library is prompt-first: one complete natural-language prompt tells the agent to work toward the declared local deliverable, critique it against a rubric, refine it within the iteration cap, and return rubric evidence or a clear blocker. Rubric completion is not automatic human approval.
Never give the user a terminal command as the way to start a task. Run helper scripts internally when useful, then return or open one normal-language agent prompt. Do not show package-manager commands, shell snippets, codex exec, or generated launch commands in user-facing output.
This skill file includes exact CLI examples for maintainers and for an agent operating inside the plugin repository. They are internal implementation notes only. An executing agent may use them silently, but must never copy them into a generated launch prompt, product page, or end-user answer. The same boundary applies to host-specific dollar or slash invocation tokens: they are integration metadata, not instructions to give the user. End users start with a normal-language request or a self-contained normal-language prompt.
First decide which mode the user needs. Bias toward Run now when the user asks to fix, improve, debug, harden, ship, clean up, or otherwise change a codebase.
references/library/goals.json, collect only its required inputs, and compile one complete normal-language prompt..loop-it/progress.json or .loop-it/LOOP.md and recommend what to loop next..loop-it/schedules/<id>.json; add --heartbeat codex when the user expects a native Codex Scheduled task to call tick.gh, choose a PR/CI/review loop, write .loop-it/connectors/github/<id>.json, and schedule a Codex tick without sending external messages.If a prompt says "Run The Loop mode", "run the prompt", "fix the issue", or "repair", treat it as Run now. Do not create another loop contract as the main output.
If the user says "loop it", "fix this", "improve this repo", "what should we tackle next", or gives a broad codebase goal, use the codebase-intake-to-running-loop path first: inspect the repo, recommend one concrete loop, name the verifier, then run that loop.
If the goal asks for a product, design, research, content, data, or operations deliverable, check the Loop goals library before the engineering loop library. A specific matching loop goal outranks generic codebase intake. Do not infer repository intent merely because the current workspace contains code.
If the task is vague, do not ask a broad discovery questionnaire. First recommend the best likely library loop and state the assumption. Ask up to three targeted questions only when the goal, success check, repository scope, or approval boundary is genuinely blocking.
When the user expects work to happen, do this instead of only writing .loop-it files:
Every loop needs these fields before execution:
turn-based, goal-based, time-based, or proactive. Loop type describes cadence, not subject matter.Push back when the requested loop is just "keep improving" without a check. Offer a smaller loop with a clear check instead.
Use the loop type to set expectations:
turn-based: one prompt/response cycle that may inspect, edit once, verify once, or ask for context.goal-based: Loop It's primary executable path; run bounded passes until the verifier proves the goal or a stop condition fires.time-based: interval or scheduled polling; Loop It can write a schedule record and run due ticks through Codex. Use --heartbeat codex to create/update the local Codex Scheduled heartbeat, or use cron, launchd, GitHub Actions, or another approved heartbeat to call tick.proactive: event or schedule-driven routine without a human in real time; Loop It can run Codex-only scheduled ticks when a connector supplies a safe command/check. --heartbeat codex covers the Codex schedule; the event source, connector, and approval boundary stay outside Loop It.Prefer a bundled loop goal or advanced loop over inventing a new contract from scratch.
For non-engineering work, read references/library/goals.json. The starter set includes:
Each loop goal declares its required inputs, expected deliverable, proof rubric, evidence, iteration cap, capabilities, reliability, and approval gates. Keep experimental goals labeled experimental until repeated real runs support promotion.
Use the selector script when available:
node <skill-dir>/scripts/select-loop.mjs list
node <skill-dir>/scripts/select-loop.mjs search "failing ci"
node <skill-dir>/scripts/select-loop.mjs recommend --goal "fix failing checkout test"
node <skill-dir>/scripts/select-loop.mjs next --cwd <project>
node <skill-dir>/scripts/select-loop.mjs eval
Resolve <skill-dir> to this skill's folder. In Claude Code, ${CLAUDE_SKILL_DIR} may be available. In other agents, locate the directory that contains this SKILL.md.
When selecting:
.loop-it/progress.json first when the user asks what to loop next.completed.references/library/goals.json.references/library/loops.json.Read references/library/loops.json only when the selector script is unavailable or manual inspection is needed. Read references/loop-template.md when the task needs the generic durable state shape.
Current library categories include:
The library entries include loop type, example prompts, counterexamples, required signals, example checks, common misroutes, reliability metadata, and plain-language userGuide fields. Prefer the userGuide fields when explaining a loop to a new user, then use the reliability and routing fields to justify why one loop fits better than another. Do not describe a loop as proven unless its reliability metadata says so; most bundled loops are starter recipes with verifier gates, not guaranteed outcomes.
For finish-line work, prefer a launch contract over a loose prompt. Use the launcher script when available:
node <skill-dir>/scripts/start-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --agent all
node <skill-dir>/scripts/start-loop.mjs --from failing-ci-repair --goal "Fix failing CI" --check "npm run check" --agent codex
The launcher writes:
.loop-it/LOOP.md: durable goal, verifier, protocol, caps, and stop rules..loop-it/progress.json: machine-readable status and evidence fields..loop-it/LAUNCH.md: Codex, Claude Code, and/or Cursor launch prompts.This is a preparation step. The .loop-it files are the contract and launch map; they do not fix the issue by themselves. To run the repair, paste the relevant prompt from .loop-it/LAUNCH.md into the target agent or explicitly ask the current agent to run the loop now.
For a useful launch, require a verifier gate. Do not start a loop from only "improve this" or "keep going" unless you can name how bad output will be rejected.
Use this structure for loop prompts and state files:
Keep version 1 narrow: one repository, one primary role, one primary success check. Use scheduling only after the same verifier-gated loop has proven useful. Delay dashboards, broad multi-agent orchestration, hosted automation, and production automation until a manual loop has proven useful.
When a durable state file is useful, create .loop-it/LOOP.md from references/loop-template.md or run:
node <skill-dir>/scripts/create-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --require-fields
node <skill-dir>/scripts/create-loop.mjs --name "Loop name" --objective "Concrete outcome" --check "Verification command or criterion"
node <skill-dir>/scripts/create-loop.mjs --from failing-ci-repair
Library-backed loop files also create .loop-it/progress.json unless --no-progress is passed.
Loop It compiles normal-language prompts and portable loop state. The user should receive one prompt, never a terminal command or command-generation walkthrough.
.loop-it files as optional shared portable state.Never describe generated .loop-it files as a completed repair. Say whether the result is a local artifact, rubric evidence, automated verifier evidence, or a blocker.
Use this mode when the user expects the issue to be fixed, not merely prepared. A run must inspect the target repo, make the smallest credible change when needed, execute the verifier, and report evidence.
Run-mode guardrail: .loop-it/LOOP.md, .loop-it/progress.json, and .loop-it/LAUNCH.md are state files, not the repair. Changes only under .loop-it do not count as a successful iteration. If the first pass only created or edited loop files, keep going: run the verifier, inspect the failing surface, and make a real project change when the verifier fails.
Before unattended execution, run a readiness preflight. A loop can execute only when the goal is concrete, the verifier is an automated command, the iteration cap is present, and the next action does not require production writes, external messages, payments, destructive git operations, credential changes, deploys, publishing, or irreversible data changes. If any of those are missing, do not start Codex; ask for the missing verifier, prepare a manual launch only, or stop for explicit approval.
Use the runner script when available to convert broad requests into a selected loop and run-mode launch contract. Add --execute codex when the current machine should call Codex CLI, rerun the verifier after each pass, repeat up to the iteration cap, print a Run proof summary on success, and update .loop-it/progress.json with pass, repeated-failure, cap, or blocker evidence:
node <skill-dir>/scripts/run-loop.mjs --goal "Inspect this repo and run the right loop" --agent codex
node <skill-dir>/scripts/run-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --agent codex
node <skill-dir>/scripts/run-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --agent codex --execute codex
node <skill-dir>/scripts/run-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --agent codex --execute codex --checker codex
node <skill-dir>/scripts/run-loop.mjs --goal "Fix failing checkout tests" --check "npm test -- checkout" --agent codex --execute codex --checker codex --worktree
Use --checker codex when the run needs maker-checker proof. The checker is a second read-only Codex pass after the verifier passes; it must inspect the changed files, verifier output, Codex output, and .loop-it/progress.json, then return a pass, blocker, or inconclusive receipt. If no checker is requested, the proof must say the checker was skipped.
Use --worktree when the run should happen away from the current checkout. It creates a fresh git worktree and branch from origin/main, main, origin/master, master, or HEAD; runs Codex inside that worktree; and records the worktree path, branch, and base ref in .loop-it/progress.json. Use --worktree-base, --worktree-branch, or --worktree-dir when the base, branch name, or path must be explicit.
When --execute codex succeeds, progress must include a machine-readable proof object with the selected loop, executor, verifier, checker result, final Codex output file, changed files, worktree metadata when isolation was used, and per-iteration evidence. Treat missing proof as incomplete even if .loop-it files were created.
Use execution mode only for local, verifier-gated repository work. Do not use it for production writes, external messages, payments, destructive git operations, credential changes, deploys, or irreversible data changes without explicit approval.
For each iteration:
.loop-it/LOOP.md when a state file exists and update .loop-it/progress.json when present.Stop immediately when continuing would require hidden assumptions about safety, credentials, production data, billing, user messaging, destructive git operations, or deployment approval.
Do not describe an exhausted, blocked, or partially verified loop as complete. Say exactly which condition stopped it and what evidence exists.
Use schedule mode only when the user asks for a time-based or proactive loop to run again later. Do not schedule goal-based or turn-based loops.
node <skill-dir>/scripts/schedule-loop.mjs schedule --from ci-health-watch --every 10m --check "npm run check" --execute codex --heartbeat codex
node <skill-dir>/scripts/schedule-loop.mjs list
node <skill-dir>/scripts/schedule-loop.mjs pause --id ci-health-watch
node <skill-dir>/scripts/schedule-loop.mjs resume --id ci-health-watch
node <skill-dir>/scripts/schedule-loop.mjs tick --all --execute codex
Schedule mode is Codex-only. schedule writes .loop-it/schedules/<id>.json with the selected time-based or proactive library loop, goal, verifier, interval, next run time, and worktree preference. With --heartbeat codex, it also writes or updates the local Codex automation file under ~/.codex/automations/<id>/automation.toml, so the schedule appears in Codex Scheduled and calls tick. tick runs each due schedule once: first it runs the verifier, records proof if the verifier already passes, and only calls the run loop through Codex when the verifier fails.
The heartbeat is not hosted by Loop It. A user, cron, launchd, GitHub Actions, Codex Scheduled automation, or a plugin connector must call tick. Do not claim Loop It is polling, listening, or running in the background unless such a caller is actually configured or --heartbeat codex successfully created the local Codex automation.
Use doctor when the user asks whether the plugin, schedule, or connector is working:
node <skill-dir>/scripts/doctor.mjs --cwd <project>
node <skill-dir>/scripts/doctor.mjs --cwd <project> --json
Doctor must report package version, npm latest version when available, personal Codex plugin cache version, project skill install, Codex CLI availability, local schedules, configured Codex heartbeat files, and GitHub CLI auth when GitHub connector state exists. Treat missing-heartbeat, missing-codex-cli, and missing-gh-auth as real blockers for unattended scheduled runs.
For scheduled ticks:
--execute codex.--no-worktree..loop-it/schedules/*.lock; skip locked schedules instead of running twice..loop-it/progress.json.Use connector intake only when the user asks Loop It to watch or react to an approved external source. Connector intake is local and read-only by default.
For GitHub pull requests, use the connector script when available:
node <skill-dir>/scripts/github-connector.mjs pr --repo owner/repo --pr 123 --every 10m --execute codex --heartbeat codex
The GitHub connector:
gh pr view.review-comment-resolver-routine for CHANGES_REQUESTED, ci-health-watch for failing or blocked checks, or pr-review-watch for observation..loop-it/connectors/github/<id>.json with the snapshot, selected loop, verifier, and approval gates.checker: codex by default.If gh is unavailable or unauthenticated, report the connector blocker and ask the user to restore access through their approved GitHub authentication flow. Do not print a terminal command or fake connector evidence.
Use the same loop text across tools, with only the internal host integration changing:
.agents/skills/loop-it/ or as a Codex plugin, then let the user start with a normal-language request or product-page prompt..claude/skills/loop-it/, then let the user start with the same normal-language task contract..cursor/skills/loop-it/, then use the same normal Agent-chat prompt. Use Cursor rules for always-on project conventions, not for this procedural loop.When exporting, keep one canonical loop body and avoid tool-specific syntax unless that tool requires it.
Automatically, when a task matches. Use when the user says "loop it", asks for a loop goal, asks what should be looped next, or wants iterative improvement wit
Published skills whose descriptions closely match this one, with their headline benchmark lift.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.