Skip to content
235 linesCodeBlameRaw
1/**
2 * Agent skills (docs.g1t.sh/guides/agent-skills/): how an agent does a kind
3 * of work with the tools it already has. A skill never adds a tool or a
4 * permission: it names the tools it uses, and an agent without one of them
5 * (in a conversation whose people can't read code, say) is told that part
6 * isn't available there.
7 *
8 * Every skill is a folder in the open SKILL.md format (skill-format.ts).
9 * Agents load them progressively: each skill's name and when to use it are
10 * in the agent's instructions, and it reads the rest with `use_skill` when
11 * a request matches.
12 *
13 * Every agent starts with g1t's foundational skills, below, which are
14 * written out as SKILL.md too (`foundationalSkillMd`). Each says, ability by
15 * ability, what works today and what is coming, and the agent is told the
16 * same, so it never claims to do what it can't. A workspace's owners can
17 * turn any skill off for one agent (`WorkspaceAgent.skills_off`, which
18 * holds foundational ids and library skill ids); turning one off takes it
19 * out of the agent's instructions and leaves its tools as they were.
20 *
21 * The workspace's own skills (written, imported, saved from a session, or
22 * followed from a repository) are its skill library (skill-library.ts).
23 *
24 * Wire shapes are snake_case.
25 */
26
27export type SkillCategory = "documents" | "research" | "data" | "code" | "communication" | "files";
28
29/** Where a skill comes from: g1t's own, written in the workspace, from the Marketplace, or learned from finished work. */
30export type SkillSource = "foundational" | "workspace" | "marketplace" | "learned";
31
32/** One thing a skill does, and whether it works today. */
33export type SkillAbility = {
34 /** Unique within its skill: `pdf`. */
35 id: string;
36 /** What it does, as the Skills tab lists it: "Make PDFs". */
37 label: string;
38 /** `ready` works today with the tools listed; `coming` is planned and the agent says so when asked. */
39 status: "ready" | "coming";
40 /** The agent's tools it uses; none for a coming ability. */
41 tools: string[];
42 /** A line on how, or what is missing: "From Markdown, as a file attached to a doc." */
43 note: string;
44};
45
46export type AgentSkill = {
47 /** `documents`, unique among skills. */
48 id: string;
49 name: string;
50 /** One line, as the Skills tab shows it. */
51 description: string;
52 /** When to use it: the description in its SKILL.md, which agents read to choose it (skill-format.ts `foundationalSkillMd`). */
53 when: string;
54 category: SkillCategory;
55 source: SkillSource;
56 /** Which release of it: foundational skills change with g1t's releases. */
57 version: string;
58 /**
59 * The playbook, in the second person, as it is put in the agent's
60 * instructions while the skill is on. Coming abilities are added to it
61 * as what the agent can't do yet.
62 */
63 instructions: string;
64 abilities: SkillAbility[];
65};
66
67/** The foundational skills' release: they change together, with g1t. */
68export const FOUNDATIONAL_SKILLS_VERSION = "2026.10";
69
70/** The formats `make_file` writes. */
71export const MAKE_FILE_FORMATS = ["pdf", "docx", "xlsx", "csv", "md"] as const;
72export type MakeFileFormat = (typeof MAKE_FILE_FORMATS)[number];
73
74const V = FOUNDATIONAL_SKILLS_VERSION;
75
76/**
77 * g1t's foundational skills, in the order the Skills tab shows them. The
78 * tools named are the agent tools in services/agents (src/tools.ts); a
79 * test there fails when one is named that doesn't exist.
80 */
81export const FOUNDATIONAL_SKILLS: AgentSkill[] = [
82 {
83 id: "documents",
84 when: "Use when someone asks for a document: a PDF, a Word document, a spreadsheet or CSV, or a doc to read and edit together in Artifacts.",
85 name: "Documents",
86 description: "PDFs, Word documents, spreadsheets and docs in Artifacts.",
87 category: "documents",
88 source: "foundational",
89 version: V,
90 instructions: [
91 "When someone asks for a document, give them the document, not a description of one.",
92 "- A doc to read and edit together: write it with create_artifact (Markdown: headings, lists, tables, task lists, callouts, Mermaid charts), or change one with edit_artifact.",
93 '- A file (a PDF, a Word document, a spreadsheet, a CSV): call make_file with the format. For pdf and docx, write the whole document as Markdown in content; for xlsx and csv, give the rows in sheets. Without an artifact, make_file makes a doc holding the content with the file attached; with one, it attaches the file to that doc. Link what it returns: "Here\'s the PDF: <link>".',
94 "- Write the finished thing: a title, short sections, real numbers and names from what you read. Never leave placeholders like [Company name] unless they asked for a template.",
95 "- PDFs and Word documents keep headings, paragraphs, bold, italic, code, lists, quotes and tables; images and charts don't carry into the file (they do in the doc). PDFs are in Latin script: say so if the text needs another.",
96 "- Long or many-step documents belong in a session (start_session), which reports back with the link.",
97 ].join("\n"),
98 abilities: [
99 { id: "doc", label: "Write and edit docs in Artifacts", status: "ready", tools: ["create_artifact", "edit_artifact", "read_artifact"], note: "Markdown with tables, task lists, callouts and Mermaid charts, edited live with people." },
100 { id: "pdf", label: "Make PDFs", status: "ready", tools: ["make_file"], note: "From Markdown, attached to a doc. Latin script." },
101 { id: "docx", label: "Word documents", status: "ready", tools: ["make_file"], note: "A .docx from Markdown, attached to a doc." },
102 { id: "xlsx", label: "Spreadsheets", status: "ready", tools: ["make_file"], note: "An .xlsx with one or more sheets, or a .csv." },
103 { id: "slides", label: "Slide decks", status: "coming", tools: [], note: "Comes with slides in Artifacts. Until then, an outline as a doc or a PDF." },
104 ],
105 },
106 {
107 id: "research",
108 when: "Use when someone asks you to research, investigate or find out what is known about something, or wants a report with sources.",
109 name: "Research",
110 description: "Reports with sources, from what the workspace knows; the open web is coming.",
111 category: "research",
112 source: "foundational",
113 version: V,
114 instructions: [
115 "When someone asks you to research something, find what is known before you write, and say where each fact comes from.",
116 "- Look in the workspace first: search_artifacts and read_artifact for specs, runbooks and decisions; search_code and read_file for how the code works; search_messages and read_thread for what was said.",
117 "- Report what you found, not what you expect: lead with the answer, then the evidence, and link every source (the artifact, file or thread). Say plainly what you couldn't find.",
118 "- A report worth keeping goes in a doc (create_artifact) with a Sources section at the end. Long research is a session's job (start_session).",
119 ].join("\n"),
120 abilities: [
121 { id: "cite", label: "Reports with sources", status: "ready", tools: ["search_artifacts", "read_artifact", "search_code", "read_file", "search_messages", "read_thread", "create_artifact"], note: "From the workspace's docs, code and chat, each source linked." },
122 { id: "search", label: "Search the web", status: "coming", tools: [], note: "Comes with web access, set per team." },
123 { id: "browse", label: "Browse and read pages", status: "coming", tools: [], note: "Comes with web access, set per team." },
124 ],
125 },
126 {
127 id: "data",
128 when: "Use when someone asks about data: analysing a CSV, JSON, log or table, totals and comparisons, charts, or results as a spreadsheet.",
129 name: "Data",
130 description: "Analyze files and tables, chart the results and hand back a spreadsheet.",
131 category: "data",
132 source: "foundational",
133 version: V,
134 instructions: [
135 "When someone asks about data, work from the data itself and show your working.",
136 "- Read it where it lives: a CSV, JSON or log file in a repository (read_file), or a table in a doc (read_artifact). Data pasted into the conversation counts too.",
137 "- You add up and compare by reasoning, not by running code, so keep tables small enough to check: count rows, say what you totalled, and round sensibly. Above a few hundred rows, say the result is an estimate, or ask for a summary.",
138 "- Charts: put a Mermaid chart in a doc. Bar or line: ```mermaid with xychart, a title, x-axis [labels], y-axis \"Unit\", then bar [values] or line [values]. Shares of a whole: pie with \"Label\" : value lines. Label axes and units.",
139 "- A table they'll work on goes back as a spreadsheet: make_file with format xlsx (or csv), header row first, numbers as numbers.",
140 ].join("\n"),
141 abilities: [
142 { id: "analyze", label: "Analyze files and tables", status: "ready", tools: ["read_file", "read_artifact"], note: "CSV, JSON and logs in repositories, tables in docs. Worked by the model, not run as code." },
143 { id: "charts", label: "Charts in docs", status: "ready", tools: ["create_artifact", "edit_artifact"], note: "Bar, line and pie charts, drawn from Mermaid in a doc." },
144 { id: "export", label: "Spreadsheets of results", status: "ready", tools: ["make_file"], note: "An .xlsx or .csv attached to a doc." },
145 { id: "dashboards", label: "Dashboards", status: "coming", tools: [], note: "Comes with dashboards in Artifacts." },
146 { id: "sql", label: "Query databases and forks", status: "coming", tools: [], note: "Comes with workspace datasets and database connections." },
147 ],
148 },
149 {
150 id: "code",
151 when: "Use when the work is code: reading or explaining it, reviewing a pull request, or getting a change made.",
152 name: "Code",
153 description: "Read and review code, and get changes made as pull requests through issues.",
154 category: "code",
155 source: "foundational",
156 version: V,
157 instructions: [
158 "When the work is code, read before you answer, and get changes made the way the team ships them.",
159 "- Find and read it: list_repositories, search_code, read_file; for history, recent_activity, get_issue and get_pull. Quote the lines you mean, with their path.",
160 "- Review on the pull request itself with review_pull (approve, request changes or comment), and leave findings with comment. Your review is advisory.",
161 "- To get a change made, draft an issue with draft_issue: what to change, why, where in the code, and how to tell it worked (the tests to add or run). Once it's filed, assigning it to @g1t makes the pull request on a runner, with checks and revisions.",
162 "- You don't run code yourself: never say you ran, built or tested something. Say what you'd run and why.",
163 ].join("\n"),
164 abilities: [
165 { id: "read", label: "Read and explain code", status: "ready", tools: ["list_repositories", "search_code", "read_file", "recent_activity"], note: "In repositories everyone in the conversation can read." },
166 { id: "review", label: "Review pull requests", status: "ready", tools: ["get_pull", "review_pull", "comment"], note: "Advisory: people still give the approvals a merge needs." },
167 { id: "pr", label: "Open pull requests", status: "ready", tools: ["draft_issue"], note: "Through an issue assigned to @g1t, which makes the pull request on a runner." },
168 { id: "run", label: "Run code on its runner", status: "coming", tools: [], note: "Comes with agents on runners." },
169 { id: "test", label: "Write and run tests itself", status: "coming", tools: [], note: "Comes with agents on runners; @g1t runs them on issues today." },
170 ],
171 },
172 {
173 id: "communication",
174 when: "Use when someone asks you to draft an email or message, summarize a thread, or write a status update.",
175 name: "Communication",
176 description: "Draft emails and messages, and summarize threads.",
177 category: "communication",
178 source: "foundational",
179 version: V,
180 instructions: [
181 "When someone asks you to write to people, or to catch them up, do it in their voice and keep it short.",
182 "- Drafts: write the email or message ready to send, with a subject line for an email, in a fenced block or a doc they can copy. You can't send email: say they send it.",
183 "- Summaries: read the thread first (read_thread, search_messages for related ones). Lead with what was decided and what is open, then who owns each next step, with links to the messages that matter.",
184 "- Status updates: from recent_activity, issues and pull requests, say what shipped, what is in progress and what is blocked.",
185 ].join("\n"),
186 abilities: [
187 { id: "draft", label: "Draft emails and messages", status: "ready", tools: [], note: "Written ready to send; sending email is coming." },
188 { id: "summarize", label: "Summarize threads", status: "ready", tools: ["search_messages", "read_thread"], note: "Decisions, open questions and owners, with links." },
189 { id: "schedule", label: "Find times and book meetings", status: "coming", tools: [], note: "Comes with calendar integrations." },
190 ],
191 },
192 {
193 id: "files",
194 when: "Use when someone needs a file in another format, or a diagram such as a flowchart, sequence or timeline.",
195 name: "Files and media",
196 description: "Convert between formats, and draw diagrams.",
197 category: "files",
198 source: "foundational",
199 version: V,
200 instructions: [
201 "When someone needs a file in another form, make it.",
202 "- Text, Markdown and tables convert to PDF, Word, Excel, CSV or Markdown with make_file. To convert a file from a repository or a doc, read it (read_file, read_artifact) and pass its content on.",
203 "- Diagrams (flows, sequences, timelines, org charts) are Mermaid fences in a doc (create_artifact).",
204 "- You can't see images or read scans, and you can't draw or edit images yet. Say so, and offer what you can do from text.",
205 ].join("\n"),
206 abilities: [
207 { id: "convert", label: "Convert between formats", status: "ready", tools: ["make_file", "read_file", "read_artifact"], note: "Markdown, text and tables to PDF, Word, Excel, CSV or Markdown." },
208 { id: "diagrams", label: "Diagrams", status: "ready", tools: ["create_artifact"], note: "Flowcharts, sequences and timelines from Mermaid in a doc." },
209 { id: "ocr", label: "Read scans and images", status: "coming", tools: [], note: "Comes with image input for agents." },
210 { id: "images", label: "Create and edit images", status: "coming", tools: [], note: "Comes with image models." },
211 ],
212 },
213];
214
215/** The ids of the foundational skills. */
216export const FOUNDATIONAL_SKILL_IDS: readonly string[] = FOUNDATIONAL_SKILLS.map((skill) => skill.id);
217
218/** Every tool a skill's ready abilities use. */
219export function skillTools(skill: AgentSkill): string[] {
220 return [...new Set(skill.abilities.filter((ability) => ability.status === "ready").flatMap((ability) => ability.tools))];
221}
222
223/** Where skills come from, and which are here yet. */
224export const SKILL_SOURCES: { source: SkillSource; label: string; status: "live" | "coming"; description: string }[] = [
225 { source: "foundational", label: "Foundational, from g1t", status: "live", description: "Every agent starts with them, updated with every release." },
226 { source: "workspace", label: "Written or imported in your workspace", status: "live", description: "Your own skills, such as how you cut a release or your brand voice: written in the editor, uploaded as SKILL.md or a zip, or read from a repository." },
227 { source: "learned", label: "Saved from a session", status: "live", description: "Drafted by the agent from a finished session, published after a person reviews it." },
228 { source: "marketplace", label: "From the Marketplace", status: "coming", description: "Skills that extensions bring, added in one step." },
229];
230
231/** The foundational skills an agent has on: every one unless `off` names it. */
232export function skillsOn(off: readonly string[] | null | undefined): AgentSkill[] {
233 const skip = new Set(off ?? []);
234 return FOUNDATIONAL_SKILLS.filter((skill) => !skip.has(skill.id));
235}