@rubytech/taskmaster 1.0.106 → 1.0.107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills-status.js +23 -3
- package/dist/agents/skills.js +1 -0
- package/dist/agents/system-prompt.js +1 -0
- package/dist/agents/tools/memory-tool.js +2 -1
- package/dist/build-info.json +3 -3
- package/dist/config/zod-schema.js +12 -1
- package/dist/control-ui/assets/index-2XyxmiR6.css +1 -0
- package/dist/control-ui/assets/{index-DtuDNTAC.js → index-B_zHmTQU.js} +823 -645
- package/dist/control-ui/assets/index-B_zHmTQU.js.map +1 -0
- package/dist/control-ui/index.html +2 -2
- package/dist/control-ui/maxy-icon.png +0 -0
- package/dist/gateway/config-reload.js +1 -0
- package/dist/gateway/control-ui.js +111 -5
- package/dist/gateway/protocol/index.js +6 -1
- package/dist/gateway/protocol/schema/agents-models-skills.js +23 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -1
- package/dist/gateway/server-http.js +6 -1
- package/dist/gateway/server-methods/brand.js +160 -0
- package/dist/gateway/server-methods/skills.js +159 -3
- package/dist/gateway/server-methods-list.js +5 -0
- package/dist/gateway/server-methods.js +2 -0
- package/dist/memory/manager.js +12 -3
- package/package.json +1 -1
- package/skills/skill-builder/SKILL.md +97 -0
- package/skills/skill-builder/references/lean-pattern.md +118 -0
- package/skills/zero-to-prototype/SKILL.md +35 -0
- package/skills/zero-to-prototype/references/discovery.md +64 -0
- package/skills/zero-to-prototype/references/prd.md +83 -0
- package/skills/zero-to-prototype/references/validation.md +67 -0
- package/taskmaster-docs/USER-GUIDE.md +58 -2
- package/templates/customer/agents/public/AGENTS.md +3 -10
- package/templates/taskmaster/agents/public/SOUL.md +0 -4
- package/templates/tradesupport/agents/public/AGENTS.md +3 -10
- package/dist/control-ui/assets/index-DjhCZlZd.css +0 -1
- package/dist/control-ui/assets/index-DtuDNTAC.js.map +0 -1
- package/skills/taskmaster/SKILL.md +0 -164
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveAgentWorkspaceDir, resolveAgentWorkspaceRoot, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
|
2
4
|
import { installSkill } from "../../agents/skills-install.js";
|
|
3
5
|
import { buildWorkspaceSkillStatus } from "../../agents/skills-status.js";
|
|
4
|
-
import { loadWorkspaceSkillEntries } from "../../agents/skills.js";
|
|
6
|
+
import { loadWorkspaceSkillEntries, resolveBundledSkillsDir } from "../../agents/skills.js";
|
|
7
|
+
import { bumpSkillsSnapshotVersion } from "../../agents/skills/refresh.js";
|
|
5
8
|
import { loadConfig, writeConfigFile } from "../../config/config.js";
|
|
6
9
|
import { getRemoteSkillEligibility } from "../../infra/skills-remote.js";
|
|
7
|
-
import { ErrorCodes, errorShape, formatValidationErrors, validateSkillsBinsParams, validateSkillsInstallParams, validateSkillsStatusParams, validateSkillsUpdateParams, } from "../protocol/index.js";
|
|
10
|
+
import { ErrorCodes, errorShape, formatValidationErrors, validateSkillsBinsParams, validateSkillsCreateParams, validateSkillsDeleteDraftParams, validateSkillsDeleteParams, validateSkillsDraftsParams, validateSkillsInstallParams, validateSkillsReadParams, validateSkillsStatusParams, validateSkillsUpdateParams, } from "../protocol/index.js";
|
|
8
11
|
function listWorkspaceDirs(cfg) {
|
|
9
12
|
const dirs = new Set();
|
|
10
13
|
const list = cfg.agents?.list;
|
|
@@ -45,6 +48,21 @@ function collectSkillBins(entries) {
|
|
|
45
48
|
}
|
|
46
49
|
return [...bins].sort();
|
|
47
50
|
}
|
|
51
|
+
function resolveWorkspaceRoot(cfg) {
|
|
52
|
+
return resolveAgentWorkspaceRoot(cfg, resolveDefaultAgentId(cfg));
|
|
53
|
+
}
|
|
54
|
+
function isPreloadedSkill(skillKey) {
|
|
55
|
+
const dir = resolveBundledSkillsDir();
|
|
56
|
+
if (!dir)
|
|
57
|
+
return false;
|
|
58
|
+
try {
|
|
59
|
+
return fs.existsSync(`${dir}/${skillKey}`) &&
|
|
60
|
+
fs.statSync(`${dir}/${skillKey}`).isDirectory();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
48
66
|
export const skillsHandlers = {
|
|
49
67
|
"skills.status": ({ params, respond }) => {
|
|
50
68
|
if (!validateSkillsStatusParams(params)) {
|
|
@@ -97,6 +115,10 @@ export const skillsHandlers = {
|
|
|
97
115
|
return;
|
|
98
116
|
}
|
|
99
117
|
const p = params;
|
|
118
|
+
if (p.enabled === false && isPreloadedSkill(p.skillKey)) {
|
|
119
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "preloaded skills cannot be disabled"));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
100
122
|
const cfg = loadConfig();
|
|
101
123
|
const skills = cfg.skills ? { ...cfg.skills } : {};
|
|
102
124
|
const entries = skills.entries ? { ...skills.entries } : {};
|
|
@@ -134,4 +156,138 @@ export const skillsHandlers = {
|
|
|
134
156
|
await writeConfigFile(nextConfig);
|
|
135
157
|
respond(true, { ok: true, skillKey: p.skillKey, config: current }, undefined);
|
|
136
158
|
},
|
|
159
|
+
"skills.read": ({ params, respond }) => {
|
|
160
|
+
if (!validateSkillsReadParams(params)) {
|
|
161
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.read params: ${formatValidationErrors(validateSkillsReadParams.errors)}`));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const p = params;
|
|
165
|
+
const cfg = loadConfig();
|
|
166
|
+
const root = resolveWorkspaceRoot(cfg);
|
|
167
|
+
const skillDir = path.join(root, "skills", p.name);
|
|
168
|
+
const skillFile = path.join(skillDir, "SKILL.md");
|
|
169
|
+
if (!fs.existsSync(skillFile)) {
|
|
170
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `skill "${p.name}" not found`));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const content = fs.readFileSync(skillFile, "utf-8");
|
|
174
|
+
const references = [];
|
|
175
|
+
const refsDir = path.join(skillDir, "references");
|
|
176
|
+
if (fs.existsSync(refsDir) && fs.statSync(refsDir).isDirectory()) {
|
|
177
|
+
for (const entry of fs.readdirSync(refsDir, { withFileTypes: true })) {
|
|
178
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
179
|
+
references.push({
|
|
180
|
+
name: entry.name,
|
|
181
|
+
content: fs.readFileSync(path.join(refsDir, entry.name), "utf-8"),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
references.sort((a, b) => a.name.localeCompare(b.name));
|
|
186
|
+
}
|
|
187
|
+
respond(true, { name: p.name, content, references }, undefined);
|
|
188
|
+
},
|
|
189
|
+
"skills.create": async ({ params, respond }) => {
|
|
190
|
+
if (!validateSkillsCreateParams(params)) {
|
|
191
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.create params: ${formatValidationErrors(validateSkillsCreateParams.errors)}`));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const p = params;
|
|
195
|
+
if (isPreloadedSkill(p.name)) {
|
|
196
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "cannot overwrite a preloaded skill"));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const cfg = loadConfig();
|
|
200
|
+
const root = resolveWorkspaceRoot(cfg);
|
|
201
|
+
const skillDir = path.join(root, "skills", p.name);
|
|
202
|
+
// If the skill already exists (user skill), remove it first so we get a clean replace
|
|
203
|
+
if (fs.existsSync(skillDir)) {
|
|
204
|
+
fs.rmSync(skillDir, { recursive: true, force: true });
|
|
205
|
+
}
|
|
206
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
207
|
+
fs.writeFileSync(path.join(skillDir, "SKILL.md"), p.skillContent, "utf-8");
|
|
208
|
+
if (p.references && p.references.length > 0) {
|
|
209
|
+
const refsDir = path.join(skillDir, "references");
|
|
210
|
+
fs.mkdirSync(refsDir, { recursive: true });
|
|
211
|
+
for (const ref of p.references) {
|
|
212
|
+
const safeName = ref.name.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
213
|
+
fs.writeFileSync(path.join(refsDir, safeName), ref.content, "utf-8");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
bumpSkillsSnapshotVersion();
|
|
217
|
+
respond(true, { ok: true, name: p.name }, undefined);
|
|
218
|
+
},
|
|
219
|
+
"skills.delete": async ({ params, respond }) => {
|
|
220
|
+
if (!validateSkillsDeleteParams(params)) {
|
|
221
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.delete params: ${formatValidationErrors(validateSkillsDeleteParams.errors)}`));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const p = params;
|
|
225
|
+
if (isPreloadedSkill(p.name)) {
|
|
226
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "preloaded skills cannot be deleted"));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const cfg = loadConfig();
|
|
230
|
+
const root = resolveWorkspaceRoot(cfg);
|
|
231
|
+
const skillDir = path.join(root, "skills", p.name);
|
|
232
|
+
if (!fs.existsSync(skillDir)) {
|
|
233
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `skill "${p.name}" not found`));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
fs.rmSync(skillDir, { recursive: true, force: true });
|
|
237
|
+
bumpSkillsSnapshotVersion();
|
|
238
|
+
respond(true, { ok: true, name: p.name }, undefined);
|
|
239
|
+
},
|
|
240
|
+
"skills.drafts": ({ params, respond }) => {
|
|
241
|
+
if (!validateSkillsDraftsParams(params)) {
|
|
242
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.drafts params: ${formatValidationErrors(validateSkillsDraftsParams.errors)}`));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const cfg = loadConfig();
|
|
246
|
+
const root = resolveWorkspaceRoot(cfg);
|
|
247
|
+
const draftsDir = path.join(root, ".skill-drafts");
|
|
248
|
+
if (!fs.existsSync(draftsDir)) {
|
|
249
|
+
respond(true, { drafts: [] }, undefined);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const drafts = [];
|
|
253
|
+
for (const entry of fs.readdirSync(draftsDir, { withFileTypes: true })) {
|
|
254
|
+
if (!entry.isDirectory())
|
|
255
|
+
continue;
|
|
256
|
+
const skillFile = path.join(draftsDir, entry.name, "SKILL.md");
|
|
257
|
+
if (!fs.existsSync(skillFile))
|
|
258
|
+
continue;
|
|
259
|
+
const skillContent = fs.readFileSync(skillFile, "utf-8");
|
|
260
|
+
const references = [];
|
|
261
|
+
const refsDir = path.join(draftsDir, entry.name, "references");
|
|
262
|
+
if (fs.existsSync(refsDir) && fs.statSync(refsDir).isDirectory()) {
|
|
263
|
+
for (const ref of fs.readdirSync(refsDir, { withFileTypes: true })) {
|
|
264
|
+
if (ref.isFile() && ref.name.endsWith(".md")) {
|
|
265
|
+
references.push({
|
|
266
|
+
name: ref.name,
|
|
267
|
+
content: fs.readFileSync(path.join(refsDir, ref.name), "utf-8"),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
references.sort((a, b) => a.name.localeCompare(b.name));
|
|
272
|
+
}
|
|
273
|
+
drafts.push({ name: entry.name, skillContent, references });
|
|
274
|
+
}
|
|
275
|
+
respond(true, { drafts }, undefined);
|
|
276
|
+
},
|
|
277
|
+
"skills.deleteDraft": ({ params, respond }) => {
|
|
278
|
+
if (!validateSkillsDeleteDraftParams(params)) {
|
|
279
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid skills.deleteDraft params: ${formatValidationErrors(validateSkillsDeleteDraftParams.errors)}`));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const p = params;
|
|
283
|
+
const cfg = loadConfig();
|
|
284
|
+
const root = resolveWorkspaceRoot(cfg);
|
|
285
|
+
const draftDir = path.join(root, ".skill-drafts", p.name);
|
|
286
|
+
if (!fs.existsSync(draftDir)) {
|
|
287
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `draft "${p.name}" not found`));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
fs.rmSync(draftDir, { recursive: true, force: true });
|
|
291
|
+
respond(true, { ok: true, name: p.name }, undefined);
|
|
292
|
+
},
|
|
137
293
|
};
|
|
@@ -36,6 +36,7 @@ import { publicChatHandlers } from "./server-methods/public-chat.js";
|
|
|
36
36
|
import { tailscaleHandlers } from "./server-methods/tailscale.js";
|
|
37
37
|
import { wifiHandlers } from "./server-methods/wifi.js";
|
|
38
38
|
import { workspacesHandlers } from "./server-methods/workspaces.js";
|
|
39
|
+
import { brandHandlers } from "./server-methods/brand.js";
|
|
39
40
|
const ADMIN_SCOPE = "operator.admin";
|
|
40
41
|
const READ_SCOPE = "operator.read";
|
|
41
42
|
const WRITE_SCOPE = "operator.write";
|
|
@@ -236,6 +237,7 @@ export const coreGatewayHandlers = {
|
|
|
236
237
|
...memoryHandlers,
|
|
237
238
|
...recordsHandlers,
|
|
238
239
|
...workspacesHandlers,
|
|
240
|
+
...brandHandlers,
|
|
239
241
|
...publicChatHandlers,
|
|
240
242
|
...tailscaleHandlers,
|
|
241
243
|
...wifiHandlers,
|
package/dist/memory/manager.js
CHANGED
|
@@ -74,6 +74,15 @@ function expandPathTemplate(pattern, ctx) {
|
|
|
74
74
|
result = result.replaceAll("{agentId}", ctx.agentId);
|
|
75
75
|
return result;
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Ensure phone numbers in memory/users/ paths include the canonical + prefix.
|
|
79
|
+
* AI agents sometimes omit the + when constructing paths (e.g. "memory/users/447734875155/...")
|
|
80
|
+
* but the session peer and filesystem convention always use + (e.g. "+447734875155").
|
|
81
|
+
* Without this, scope patterns like memory/users/{peer}/** won't match the path.
|
|
82
|
+
*/
|
|
83
|
+
function normalizePhoneInMemoryPath(relPath) {
|
|
84
|
+
return relPath.replace(/^(memory\/users\/)(\d)/i, "$1+$2");
|
|
85
|
+
}
|
|
77
86
|
/**
|
|
78
87
|
* Simple glob pattern matcher supporting * and **.
|
|
79
88
|
* - * matches any characters except /
|
|
@@ -517,7 +526,7 @@ export class MemoryIndexManager {
|
|
|
517
526
|
return this.syncing;
|
|
518
527
|
}
|
|
519
528
|
async readFile(params) {
|
|
520
|
-
const relPath = normalizeRelPath(params.relPath);
|
|
529
|
+
const relPath = normalizePhoneInMemoryPath(normalizeRelPath(params.relPath));
|
|
521
530
|
if (!relPath || !isMemoryPath(relPath)) {
|
|
522
531
|
throw new Error("path required");
|
|
523
532
|
}
|
|
@@ -552,7 +561,7 @@ export class MemoryIndexManager {
|
|
|
552
561
|
* matching the session's scope configuration.
|
|
553
562
|
*/
|
|
554
563
|
async writeFile(params) {
|
|
555
|
-
const relPath = normalizeRelPath(params.relPath);
|
|
564
|
+
const relPath = normalizePhoneInMemoryPath(normalizeRelPath(params.relPath));
|
|
556
565
|
if (!relPath || !isMemoryPath(relPath)) {
|
|
557
566
|
throw new Error("path required (must be in memory/ directory)");
|
|
558
567
|
}
|
|
@@ -598,7 +607,7 @@ export class MemoryIndexManager {
|
|
|
598
607
|
let relPath;
|
|
599
608
|
if (params.destFolder) {
|
|
600
609
|
// Explicit folder — use as-is (scope checking enforces access)
|
|
601
|
-
relPath = `${params.destFolder}/${params.destFilename}
|
|
610
|
+
relPath = normalizePhoneInMemoryPath(`${params.destFolder}/${params.destFilename}`);
|
|
602
611
|
}
|
|
603
612
|
else {
|
|
604
613
|
// Default: memory/users/{peer}/media/{filename}
|
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-builder
|
|
3
|
+
description: "Guide the user through creating a new lean skill — collect name, description, behaviour rules, and references, then save as a draft for the user to install via the Control Panel."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Skill Builder
|
|
9
|
+
|
|
10
|
+
A deterministic walkthrough for creating new lean skills. Follow each step in order. Be conversational — one question at a time.
|
|
11
|
+
|
|
12
|
+
## When to Activate
|
|
13
|
+
|
|
14
|
+
The admin requests a new skill, asks to "create a skill", "add a skill", or invokes `/skill-builder`.
|
|
15
|
+
|
|
16
|
+
## Before Starting
|
|
17
|
+
|
|
18
|
+
Load `references/lean-pattern.md` for the template and examples. Use it throughout as your reference for correct structure.
|
|
19
|
+
|
|
20
|
+
## Step 1: Understand the Purpose
|
|
21
|
+
|
|
22
|
+
Ask: **"What should this skill do?"**
|
|
23
|
+
|
|
24
|
+
Listen for:
|
|
25
|
+
- What capability it adds (scheduling, quoting, inventory, etc.)
|
|
26
|
+
- When it should activate (what triggers it)
|
|
27
|
+
- What tools or data it needs (memory, web search, file access, etc.)
|
|
28
|
+
|
|
29
|
+
Clarify until you can describe the skill in one sentence. This becomes the `description` in frontmatter.
|
|
30
|
+
|
|
31
|
+
## Step 2: Choose a Name
|
|
32
|
+
|
|
33
|
+
Propose a name based on the purpose. Names must be:
|
|
34
|
+
- Lowercase
|
|
35
|
+
- Hyphen-separated (e.g. `inventory-management`)
|
|
36
|
+
- Short and descriptive
|
|
37
|
+
|
|
38
|
+
Confirm with the user.
|
|
39
|
+
|
|
40
|
+
## Step 3: Define Behaviour
|
|
41
|
+
|
|
42
|
+
Ask what rules the agent should follow when using this skill:
|
|
43
|
+
- **Tone and style** — formal, casual, WhatsApp-short?
|
|
44
|
+
- **Activation conditions** — when exactly should the agent use this skill?
|
|
45
|
+
- **Hard boundaries** — what should the agent never do?
|
|
46
|
+
- **Data sources** — where does the skill's knowledge live? (memory, external API, files)
|
|
47
|
+
- **Escalation** — when should it hand off to admin?
|
|
48
|
+
|
|
49
|
+
Not every skill needs all of these. Only include what's relevant.
|
|
50
|
+
|
|
51
|
+
## Step 4: Decide on References
|
|
52
|
+
|
|
53
|
+
If the skill has detailed procedures, templates, or data formats, those belong in `references/` files — not inline in SKILL.md.
|
|
54
|
+
|
|
55
|
+
Ask: **"Are there any detailed procedures, templates, or formats this skill needs?"**
|
|
56
|
+
|
|
57
|
+
For each reference file:
|
|
58
|
+
- Give it a descriptive filename (e.g. `event-format.md`, `quoting-rules.md`)
|
|
59
|
+
- Collect the content from the user — they can dictate, paste, or describe it and you draft it
|
|
60
|
+
|
|
61
|
+
If the skill is simple enough to fit in SKILL.md alone (under ~30 lines of instructions), skip references.
|
|
62
|
+
|
|
63
|
+
## Step 5: Compose the Skill
|
|
64
|
+
|
|
65
|
+
Using the lean pattern from `references/lean-pattern.md`, compose:
|
|
66
|
+
|
|
67
|
+
1. **SKILL.md** — frontmatter (`name`, `description`) + activation conditions + behaviour rules + references index
|
|
68
|
+
2. **Reference files** — one per detailed topic
|
|
69
|
+
|
|
70
|
+
Show the user the complete SKILL.md content and each reference file. Ask them to review.
|
|
71
|
+
|
|
72
|
+
## Step 6: Save the Draft
|
|
73
|
+
|
|
74
|
+
Use your `write` tool to save the skill as a draft:
|
|
75
|
+
|
|
76
|
+
1. Create `../../.skill-drafts/{name}/SKILL.md` with the composed content
|
|
77
|
+
2. For each reference file: create `../../.skill-drafts/{name}/references/{filename}`
|
|
78
|
+
|
|
79
|
+
The `../../` resolves from your agent directory to the workspace root. The `.skill-drafts/` folder at the workspace root is where the Control Panel looks for drafts.
|
|
80
|
+
|
|
81
|
+
**Important:** Write to `.skill-drafts/`, NOT directly to `skills/`. The user installs the skill through the Control Panel.
|
|
82
|
+
|
|
83
|
+
## Step 7: Direct to Control Panel
|
|
84
|
+
|
|
85
|
+
Tell the user:
|
|
86
|
+
|
|
87
|
+
> "Your skill draft is ready. To install it:
|
|
88
|
+
> 1. Open the **Control Panel** → **Advanced** → **Skills**
|
|
89
|
+
> 2. Click **Add Skill**
|
|
90
|
+
> 3. Your draft will appear under 'Import from draft' — click it to load
|
|
91
|
+
> 4. Review the content and click **Save Skill**
|
|
92
|
+
>
|
|
93
|
+
> Once saved, the skill will be available to agents on the next message."
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**Remember:** Be conversational. Don't dump all questions at once. Guide through each step one at a time.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Lean SKILL.md Pattern
|
|
2
|
+
|
|
3
|
+
Skills teach agents specialised capabilities. Each skill is a directory containing a `SKILL.md` file and optional `references/` subdirectory.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
skills/
|
|
9
|
+
my-skill/
|
|
10
|
+
SKILL.md ← Main file (lean index)
|
|
11
|
+
references/
|
|
12
|
+
detailed-guide.md ← Loaded on demand via skill_read
|
|
13
|
+
templates.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## SKILL.md Template
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
---
|
|
20
|
+
name: my-skill
|
|
21
|
+
description: "One-line summary of what this skill does — used for agent routing."
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# My Skill
|
|
25
|
+
|
|
26
|
+
Applies when [activation conditions].
|
|
27
|
+
|
|
28
|
+
## When to Activate
|
|
29
|
+
|
|
30
|
+
- [Trigger condition 1]
|
|
31
|
+
- [Trigger condition 2]
|
|
32
|
+
|
|
33
|
+
## Behaviour
|
|
34
|
+
|
|
35
|
+
[Concise rules — keep this section short. Move detailed procedures to references.]
|
|
36
|
+
|
|
37
|
+
## References
|
|
38
|
+
|
|
39
|
+
Load `references/detailed-guide.md` for [what it covers].
|
|
40
|
+
Load `references/templates.md` for [what it covers].
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Principles
|
|
44
|
+
|
|
45
|
+
1. **SKILL.md is an index, not a manual.** Keep it under 30 lines of instructions. The agent reads it on every activation — bloated skills waste context.
|
|
46
|
+
|
|
47
|
+
2. **References hold the detail.** Procedures, templates, data formats, and examples go in `references/`. The agent loads them on demand with `skill_read`.
|
|
48
|
+
|
|
49
|
+
3. **Frontmatter is required.** Every SKILL.md must start with YAML frontmatter containing `name` and `description`. Missing `description` causes the skill to be silently skipped.
|
|
50
|
+
|
|
51
|
+
4. **Description drives routing.** The description is injected into the agent's prompt as part of the available skills list. Make it specific enough that the agent activates the skill for the right messages.
|
|
52
|
+
|
|
53
|
+
5. **Behaviour, not data.** Skills define how the agent should act. Business-specific data (pricing, customer info, hours) belongs in memory, not in the skill file. Skills are generic; memory is specific.
|
|
54
|
+
|
|
55
|
+
## Optional Frontmatter Fields
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
metadata: {"taskmaster":{"always":true,"emoji":"📦","primaryEnv":"MY_API_KEY"}}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Field | Purpose |
|
|
62
|
+
|-------|---------|
|
|
63
|
+
| `always` | Always include in prompt (skip eligibility checks) |
|
|
64
|
+
| `emoji` | Display emoji in the Control Panel |
|
|
65
|
+
| `primaryEnv` | Env var for API key — enables the key input field in the UI |
|
|
66
|
+
| `requires.bins` | Required binaries (e.g. `["curl"]`) |
|
|
67
|
+
| `requires.env` | Required environment variables |
|
|
68
|
+
|
|
69
|
+
Most user-created skills need only `name` and `description`.
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Simple skill (no references)
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
---
|
|
77
|
+
name: weather
|
|
78
|
+
description: "Provide weather context for scheduling and outdoor work decisions."
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
# Weather
|
|
82
|
+
|
|
83
|
+
When scheduling or planning outdoor work, check weather conditions.
|
|
84
|
+
|
|
85
|
+
## When to Activate
|
|
86
|
+
|
|
87
|
+
- Customer asks about weather
|
|
88
|
+
- Scheduling outdoor appointments
|
|
89
|
+
- Weather might affect planned work
|
|
90
|
+
|
|
91
|
+
## Behaviour
|
|
92
|
+
|
|
93
|
+
Use the `web_search` tool to check current weather for the business location.
|
|
94
|
+
Keep weather info brief — one or two sentences unless asked for detail.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Lean skill with references
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
---
|
|
101
|
+
name: event-management
|
|
102
|
+
description: "Manage anything time-bound: appointments, meetings, reminders, follow-ups."
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# Event Management
|
|
106
|
+
|
|
107
|
+
Applies when handling anything time-bound.
|
|
108
|
+
|
|
109
|
+
## When to Activate
|
|
110
|
+
|
|
111
|
+
- Customer requests or confirms an appointment
|
|
112
|
+
- Business owner asks to schedule, reschedule, or cancel something
|
|
113
|
+
- A reminder or follow-up needs to be recorded
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
Load `references/events.md` for the standard event template, file naming, and calendar query instructions.
|
|
118
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zero-to-prototype
|
|
3
|
+
description: "Guide business owners from a raw idea to a validated concept — customer discovery, assumption testing, value proposition, and a simple PRD. For entrepreneurs exploring new products, services, or pivots."
|
|
4
|
+
metadata: {"taskmaster":{"emoji":"🚀"}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Zero to Prototype
|
|
8
|
+
|
|
9
|
+
Helps business owners validate ideas before investing time and money. Covers the full journey from initial concept to a clear product requirement document.
|
|
10
|
+
|
|
11
|
+
## When to Activate
|
|
12
|
+
|
|
13
|
+
- Owner says they have an idea for a new product, service, or offering
|
|
14
|
+
- Owner wants to validate whether something is worth pursuing
|
|
15
|
+
- Owner asks about customer discovery, market validation, or testing assumptions
|
|
16
|
+
- Owner wants to write a PRD or product brief
|
|
17
|
+
- Phrases like "pressure test this idea", "is this worth building", "help me think through this"
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
Walk through each phase conversationally. Don't dump all phases at once — progress naturally based on where the owner is.
|
|
22
|
+
|
|
23
|
+
**Phase 1 — Capture the idea.** Understand what they want to build and why. Load `references/discovery.md`.
|
|
24
|
+
|
|
25
|
+
**Phase 2 — Validate assumptions.** Identify and test the riskiest assumptions. Load `references/validation.md`.
|
|
26
|
+
|
|
27
|
+
**Phase 3 — Define the product.** Turn validated concepts into a clear PRD. Load `references/prd.md`.
|
|
28
|
+
|
|
29
|
+
## References
|
|
30
|
+
|
|
31
|
+
Load reference files on demand as each phase is reached — not all at once.
|
|
32
|
+
|
|
33
|
+
- `references/discovery.md` — customer discovery framework, interview questions, market signals
|
|
34
|
+
- `references/validation.md` — assumption mapping, validation techniques, go/no-go criteria
|
|
35
|
+
- `references/prd.md` — PRD template, prioritisation, scope definition
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Customer Discovery
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Understand the problem before designing the solution. Most failed products solve a problem nobody has, or solve the right problem for the wrong audience.
|
|
6
|
+
|
|
7
|
+
## Step 1: Articulate the Idea
|
|
8
|
+
|
|
9
|
+
Get the owner to state their idea in one sentence:
|
|
10
|
+
|
|
11
|
+
> "[Product/service] helps [target audience] [solve problem] by [mechanism]."
|
|
12
|
+
|
|
13
|
+
If they can't fill this in, they don't have a clear idea yet. Help them by asking:
|
|
14
|
+
- Who specifically would use this?
|
|
15
|
+
- What problem does it solve for them?
|
|
16
|
+
- How do they solve this problem today (without your product)?
|
|
17
|
+
- Why would they switch to your solution?
|
|
18
|
+
|
|
19
|
+
## Step 2: Identify the Target Customer
|
|
20
|
+
|
|
21
|
+
Don't accept "everyone" or "small businesses". Get specific:
|
|
22
|
+
- **Demographics** — age, location, income, profession
|
|
23
|
+
- **Behaviour** — what do they currently do? where do they hang out?
|
|
24
|
+
- **Pain** — what frustrates them about the current solution?
|
|
25
|
+
|
|
26
|
+
Ask: "If you could only sell to one type of person, who would it be?"
|
|
27
|
+
|
|
28
|
+
## Step 3: Customer Conversations
|
|
29
|
+
|
|
30
|
+
The owner needs to talk to potential customers. Not friends. Not family. Real prospects.
|
|
31
|
+
|
|
32
|
+
### What to Ask (5 Key Questions)
|
|
33
|
+
|
|
34
|
+
1. **"Tell me about the last time you [experienced the problem]."** — Gets real stories, not hypotheticals.
|
|
35
|
+
2. **"What did you do about it?"** — Reveals current solutions and willingness to act.
|
|
36
|
+
3. **"What's the most annoying part of how you handle this today?"** — Finds the pain point.
|
|
37
|
+
4. **"If you could wave a magic wand, what would be different?"** — Reveals desires without anchoring to your solution.
|
|
38
|
+
5. **"Would you pay to solve this? How much?"** — Tests willingness to pay.
|
|
39
|
+
|
|
40
|
+
### Rules
|
|
41
|
+
|
|
42
|
+
- **Don't pitch.** You're learning, not selling.
|
|
43
|
+
- **Don't ask "would you use this?"** — everyone says yes to be polite.
|
|
44
|
+
- **Talk to at least 5 people** before drawing conclusions.
|
|
45
|
+
- **Look for patterns** — one person's pain is anecdotal. Three people's pain is a signal.
|
|
46
|
+
|
|
47
|
+
## Step 4: Market Signals
|
|
48
|
+
|
|
49
|
+
Help the owner assess whether the market supports the idea:
|
|
50
|
+
|
|
51
|
+
- **Search volume** — are people searching for solutions? (Use web search to check)
|
|
52
|
+
- **Competitors** — who else solves this? What do they charge? What do reviews say?
|
|
53
|
+
- **Market size** — how many potential customers exist? Is the market growing?
|
|
54
|
+
- **Timing** — why now? What's changed that makes this possible or necessary?
|
|
55
|
+
|
|
56
|
+
## Output
|
|
57
|
+
|
|
58
|
+
By the end of discovery, the owner should have:
|
|
59
|
+
1. A clear one-sentence idea statement
|
|
60
|
+
2. A specific target customer profile
|
|
61
|
+
3. At least 3 customer conversation summaries (or a plan to do them)
|
|
62
|
+
4. A market landscape overview
|
|
63
|
+
|
|
64
|
+
Save these to memory for use in the validation and PRD phases.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Product Requirement Document
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Turn the validated idea into a clear, actionable document that defines what to build, for whom, and why.
|
|
6
|
+
|
|
7
|
+
## PRD Template
|
|
8
|
+
|
|
9
|
+
Walk the owner through each section. Write the PRD collaboratively — don't generate it in isolation.
|
|
10
|
+
|
|
11
|
+
### 1. Problem Statement
|
|
12
|
+
|
|
13
|
+
One paragraph. What problem exists, who has it, and why current solutions fall short.
|
|
14
|
+
|
|
15
|
+
Draw from discovery phase: customer conversations, pain points, market gaps.
|
|
16
|
+
|
|
17
|
+
### 2. Target Customer
|
|
18
|
+
|
|
19
|
+
Specific profile from discovery:
|
|
20
|
+
- Who they are (demographics, role, context)
|
|
21
|
+
- What they currently do (workarounds, competitors they use)
|
|
22
|
+
- What they need (the gap your product fills)
|
|
23
|
+
|
|
24
|
+
### 3. Value Proposition
|
|
25
|
+
|
|
26
|
+
One sentence: "We help [target customer] [achieve outcome] by [mechanism], unlike [current alternative] which [limitation]."
|
|
27
|
+
|
|
28
|
+
### 4. Core Features
|
|
29
|
+
|
|
30
|
+
List the minimum features needed for the product to deliver its value proposition. No more.
|
|
31
|
+
|
|
32
|
+
For each feature:
|
|
33
|
+
- **What it does** (user-facing description)
|
|
34
|
+
- **Why it matters** (which customer need it addresses)
|
|
35
|
+
- **Priority** (Must-have / Should-have / Nice-to-have)
|
|
36
|
+
|
|
37
|
+
Use the MoSCoW method:
|
|
38
|
+
- **Must-have** — Product is useless without these
|
|
39
|
+
- **Should-have** — Significantly improves the product
|
|
40
|
+
- **Could-have** — Nice but not critical
|
|
41
|
+
- **Won't-have** — Explicitly out of scope for v1
|
|
42
|
+
|
|
43
|
+
### 5. User Journey
|
|
44
|
+
|
|
45
|
+
Walk through the primary use case step by step:
|
|
46
|
+
1. How does the customer discover the product?
|
|
47
|
+
2. What's their first interaction?
|
|
48
|
+
3. How do they get value for the first time?
|
|
49
|
+
4. What keeps them coming back?
|
|
50
|
+
|
|
51
|
+
### 6. Success Metrics
|
|
52
|
+
|
|
53
|
+
How will the owner know this is working?
|
|
54
|
+
|
|
55
|
+
| Metric | Target | Timeframe |
|
|
56
|
+
|--------|--------|-----------|
|
|
57
|
+
| e.g. Signups | 50 | First month |
|
|
58
|
+
| e.g. Paying customers | 10 | First 3 months |
|
|
59
|
+
| e.g. Retention | 70% month-over-month | Month 2+ |
|
|
60
|
+
|
|
61
|
+
Pick 3-5 metrics. No more. Focus on outcomes, not vanity metrics.
|
|
62
|
+
|
|
63
|
+
### 7. Scope and Constraints
|
|
64
|
+
|
|
65
|
+
- **Budget** — what can the owner invest?
|
|
66
|
+
- **Timeline** — when do they need it by?
|
|
67
|
+
- **Technical constraints** — platform, integrations, dependencies
|
|
68
|
+
- **Regulatory** — compliance, data protection, licensing
|
|
69
|
+
|
|
70
|
+
### 8. Risks and Mitigations
|
|
71
|
+
|
|
72
|
+
Top 3 risks from validation phase and how to address them.
|
|
73
|
+
|
|
74
|
+
### 9. Next Steps
|
|
75
|
+
|
|
76
|
+
Concrete actions with owners and deadlines:
|
|
77
|
+
1. What needs to happen first?
|
|
78
|
+
2. Who does what?
|
|
79
|
+
3. When is the first checkpoint?
|
|
80
|
+
|
|
81
|
+
## Output
|
|
82
|
+
|
|
83
|
+
Save the completed PRD to memory. The owner now has a document they can share with developers, investors, or partners.
|