@rubytech/taskmaster 1.21.2 → 1.21.3
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.
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { PRELOADED_SKILL_AGENTS } from "./types.js";
|
|
2
2
|
const DEFAULT_AGENTS = ["admin", "public"];
|
|
3
3
|
/**
|
|
4
|
-
* Resolve which agents can access a skill.
|
|
5
|
-
* Preloaded skills use the hardcoded map (not overridable).
|
|
6
|
-
* User/licensed skills use config
|
|
4
|
+
* Resolve which agents can access a given skill.
|
|
5
|
+
* - Preloaded skills use the hardcoded map (not overridable by users).
|
|
6
|
+
* - User/licensed skills use `config.skills.entries[name].agents`, defaulting to both agents.
|
|
7
7
|
*/
|
|
8
8
|
export function resolveSkillAgents(skillName, isPreloaded, config) {
|
|
9
|
-
if (isPreloaded)
|
|
9
|
+
if (isPreloaded)
|
|
10
10
|
return PRELOADED_SKILL_AGENTS[skillName] ?? DEFAULT_AGENTS;
|
|
11
|
-
}
|
|
12
11
|
const entry = config?.skills?.entries?.[skillName];
|
|
13
12
|
return entry?.agents ?? DEFAULT_AGENTS;
|
|
14
13
|
}
|
|
@@ -1 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Hardcoded agent access for preloaded (bundled) skills.
|
|
3
|
+
* Users cannot override these — they are enforced at prompt build time.
|
|
4
|
+
*/
|
|
5
|
+
export const PRELOADED_SKILL_AGENTS = {
|
|
6
|
+
"system-admin": ["admin"],
|
|
7
|
+
"log-review": ["admin"],
|
|
8
|
+
"strategic-proactivity": ["admin"],
|
|
9
|
+
"skill-builder": ["admin"],
|
|
10
|
+
"anthropic": ["admin"],
|
|
11
|
+
"openai": ["admin"],
|
|
12
|
+
"google-ai": ["admin"],
|
|
13
|
+
"tavily": ["admin"],
|
|
14
|
+
"twilio": ["admin"],
|
|
15
|
+
"brevo": ["admin"],
|
|
16
|
+
"stripe": ["admin"],
|
|
17
|
+
"taskmaster": ["admin", "public"],
|
|
18
|
+
"business-assistant": ["admin", "public"],
|
|
19
|
+
"event-management": ["admin", "public"],
|
|
20
|
+
"weather": ["admin", "public"],
|
|
21
|
+
"image-gen": ["admin", "public"],
|
|
22
|
+
"qr-code": ["admin", "public"],
|
|
23
|
+
"sales-closer": ["admin", "public"],
|
|
24
|
+
"zero-to-prototype": ["admin", "public"],
|
|
25
|
+
};
|
|
@@ -9,6 +9,7 @@ import { parseFrontmatter, resolveTaskmasterMetadata, resolveSkillInvocationPoli
|
|
|
9
9
|
import { resolvePluginSkillDirs } from "./plugin-skills.js";
|
|
10
10
|
import { hasMarker } from "../../license/skill-pack.js";
|
|
11
11
|
import { serializeByKey } from "./serialize.js";
|
|
12
|
+
import { resolveSkillAgents } from "./agent-scope.js";
|
|
12
13
|
const fsp = fs.promises;
|
|
13
14
|
const skillsLogger = createSubsystemLogger("skills");
|
|
14
15
|
function escapeXml(str) {
|
|
@@ -94,7 +95,21 @@ function debugSkillCommandOnce(messageKey, message, meta) {
|
|
|
94
95
|
skillCommandDebugOnce.add(messageKey);
|
|
95
96
|
skillsLogger.debug(message, meta);
|
|
96
97
|
}
|
|
97
|
-
function
|
|
98
|
+
function resolveBundledSkillNamesSet() {
|
|
99
|
+
const dir = resolveBundledSkillsDir();
|
|
100
|
+
if (!dir)
|
|
101
|
+
return new Set();
|
|
102
|
+
try {
|
|
103
|
+
return new Set(fs
|
|
104
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
105
|
+
.filter((d) => d.isDirectory())
|
|
106
|
+
.map((d) => d.name));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return new Set();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function filterSkillEntries(entries, config, skillFilter, eligibility, agentId) {
|
|
98
113
|
let filtered = entries.filter((entry) => shouldIncludeSkill({ entry, config, eligibility }));
|
|
99
114
|
// If skillFilter is provided, only include skills in the filter list.
|
|
100
115
|
if (skillFilter !== undefined) {
|
|
@@ -107,6 +122,15 @@ function filterSkillEntries(entries, config, skillFilter, eligibility) {
|
|
|
107
122
|
: [];
|
|
108
123
|
console.log(`[skills] After filter: ${filtered.map((entry) => entry.skill.name).join(", ")}`);
|
|
109
124
|
}
|
|
125
|
+
// Agent-level filtering: exclude skills not accessible to this agent.
|
|
126
|
+
if (agentId) {
|
|
127
|
+
const bundledNames = resolveBundledSkillNamesSet();
|
|
128
|
+
filtered = filtered.filter((entry) => {
|
|
129
|
+
const isPreloaded = bundledNames.has(entry.skill.name);
|
|
130
|
+
const allowedAgents = resolveSkillAgents(entry.skill.name, isPreloaded, config);
|
|
131
|
+
return allowedAgents.includes(agentId);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
110
134
|
return filtered;
|
|
111
135
|
}
|
|
112
136
|
const SKILL_COMMAND_MAX_LENGTH = 32;
|
|
@@ -214,7 +238,7 @@ function loadSkillEntries(workspaceDir, opts) {
|
|
|
214
238
|
}
|
|
215
239
|
export function buildWorkspaceSkillSnapshot(workspaceDir, opts) {
|
|
216
240
|
const skillEntries = opts?.entries ?? loadSkillEntries(workspaceDir, opts);
|
|
217
|
-
const eligible = filterSkillEntries(skillEntries, opts?.config, opts?.skillFilter, opts?.eligibility);
|
|
241
|
+
const eligible = filterSkillEntries(skillEntries, opts?.config, opts?.skillFilter, opts?.eligibility, opts?.agentId);
|
|
218
242
|
const promptEntries = eligible.filter((entry) => entry.invocation?.disableModelInvocation !== true);
|
|
219
243
|
const resolvedSkills = promptEntries.map((entry) => entry.skill);
|
|
220
244
|
const remoteNote = opts?.eligibility?.remote?.note?.trim();
|
|
@@ -233,7 +257,7 @@ export function buildWorkspaceSkillSnapshot(workspaceDir, opts) {
|
|
|
233
257
|
}
|
|
234
258
|
export function buildWorkspaceSkillsPrompt(workspaceDir, opts) {
|
|
235
259
|
const skillEntries = opts?.entries ?? loadSkillEntries(workspaceDir, opts);
|
|
236
|
-
const eligible = filterSkillEntries(skillEntries, opts?.config, opts?.skillFilter, opts?.eligibility);
|
|
260
|
+
const eligible = filterSkillEntries(skillEntries, opts?.config, opts?.skillFilter, opts?.eligibility, opts?.agentId);
|
|
237
261
|
const promptEntries = eligible.filter((entry) => entry.invocation?.disableModelInvocation !== true);
|
|
238
262
|
const remoteNote = opts?.eligibility?.remote?.note?.trim();
|
|
239
263
|
return [remoteNote, formatSkillsForPromptTaskmaster(promptEntries)].filter(Boolean).join("\n");
|
|
@@ -354,8 +378,8 @@ export async function syncBundledSkillsToWorkspace(workspaceDir, opts) {
|
|
|
354
378
|
}
|
|
355
379
|
return { synced };
|
|
356
380
|
}
|
|
357
|
-
export function filterWorkspaceSkillEntries(entries, config) {
|
|
358
|
-
return filterSkillEntries(entries, config);
|
|
381
|
+
export function filterWorkspaceSkillEntries(entries, config, agentId) {
|
|
382
|
+
return filterSkillEntries(entries, config, undefined, undefined, agentId);
|
|
359
383
|
}
|
|
360
384
|
export function buildWorkspaceSkillCommandSpecs(workspaceDir, opts) {
|
|
361
385
|
const skillEntries = opts?.entries ?? loadSkillEntries(workspaceDir, opts);
|
package/dist/build-info.json
CHANGED
package/package.json
CHANGED
|
@@ -961,7 +961,7 @@ Tap the delete icon on a user skill's card. You will be asked to confirm before
|
|
|
961
961
|
|
|
962
962
|
#### Skill Packs (Licensed Skills)
|
|
963
963
|
|
|
964
|
-
Your Taskmaster provider can send you additional skills as **skill packs** — signed files that install licensed capabilities onto your device. These are skills built specifically for your business or industry.
|
|
964
|
+
Your Taskmaster provider can send you additional skills as **skill packs** — signed files that install licensed capabilities onto your device. These are skills built specifically for your business or industry. A pack can contain a single skill or a **bundle** of multiple related skills (e.g. all the skills needed for estate agency work).
|
|
965
965
|
|
|
966
966
|
**How to install a skill pack:**
|
|
967
967
|
|
|
@@ -970,7 +970,9 @@ Your Taskmaster provider can send you additional skills as **skill packs** — s
|
|
|
970
970
|
3. Ask your assistant to install it — for example: "Please install this skill pack"
|
|
971
971
|
4. The assistant verifies the file is genuine and licensed for your device, then installs it
|
|
972
972
|
|
|
973
|
-
Once installed,
|
|
973
|
+
Once installed, each skill appears in the Skills tab with a **Licensed** badge. Bundles install all their skills in one step — you only forward one file.
|
|
974
|
+
|
|
975
|
+
**Sharing your Device ID:** Your provider needs your device ID to create a skill pack for your device. Find it on the **Setup** page → **License** card → tap the info icon → copy the **Device ID** using the copy button. Alternatively, ask your admin assistant: "What's my device ID?"
|
|
974
976
|
|
|
975
977
|
**Updating a skill pack:** Your provider sends you a new version of the file. Follow the same steps — forwarding and asking your assistant to install. The new version replaces the old one automatically.
|
|
976
978
|
|