@meltstudio/meltctl 5.26.0 → 5.27.0

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.
Files changed (2) hide show
  1. package/dist/index.js +173 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7499,7 +7499,7 @@ var CLI_VERSION;
7499
7499
  var init_version = __esm({
7500
7500
  "src/utils/version.ts"() {
7501
7501
  "use strict";
7502
- CLI_VERSION = "5.26.0";
7502
+ CLI_VERSION = "5.27.0";
7503
7503
  }
7504
7504
  });
7505
7505
 
@@ -26933,6 +26933,43 @@ function createTemplatesResource(config2) {
26933
26933
  };
26934
26934
  }
26935
26935
 
26936
+ // ../sdk/dist/resources/skills.js
26937
+ function skillPath(plugin, skill) {
26938
+ return `/skills/${encodeURIComponent(plugin)}/${encodeURIComponent(skill)}`;
26939
+ }
26940
+ function createSkillsResource(config2) {
26941
+ return {
26942
+ /** Every Melt skill (`melt-dev:plan`, …) with its frontmatter description. Auth-only. */
26943
+ async list() {
26944
+ const { data, status } = await apiFetch(config2, "/skills");
26945
+ if (status !== 200)
26946
+ throw new Error(data.error ?? `Failed to list skills (${status})`);
26947
+ return data.skills;
26948
+ },
26949
+ /** One skill's instructions plus the list of its reference files. */
26950
+ async get(plugin, skill, opts = {}) {
26951
+ const query = opts.client ? `?client=${encodeURIComponent(opts.client)}` : "";
26952
+ const { data, status } = await apiFetch(config2, `${skillPath(plugin, skill)}${query}`);
26953
+ if (status === 404)
26954
+ throw new Error(`Skill not found: ${plugin}:${skill}`);
26955
+ if (status !== 200)
26956
+ throw new Error(data.error ?? `Failed to fetch skill (${status})`);
26957
+ return data;
26958
+ },
26959
+ /** One file from the skill's folder, by the path `get` lists (`references/x.md`). */
26960
+ async getFile(plugin, skill, path10, opts = {}) {
26961
+ const params = new URLSearchParams({ path: path10 });
26962
+ if (opts.client)
26963
+ params.set("client", opts.client);
26964
+ const { data, status } = await apiFetch(config2, `${skillPath(plugin, skill)}/file?${params.toString()}`);
26965
+ if (status !== 200) {
26966
+ throw new Error(data.error ?? `Failed to fetch skill file (${status})`);
26967
+ }
26968
+ return data;
26969
+ }
26970
+ };
26971
+ }
26972
+
26936
26973
  // ../sdk/dist/resources/auth.js
26937
26974
  function createAuthResource(config2) {
26938
26975
  return {
@@ -28138,6 +28175,7 @@ function createMeltClient(config2) {
28138
28175
  feedback: createFeedbackResource(config2),
28139
28176
  coins: createCoinsResource(config2),
28140
28177
  templates: createTemplatesResource(config2),
28178
+ skills: createSkillsResource(config2),
28141
28179
  auth: createAuthResource(config2),
28142
28180
  people: createPeopleResource(config2),
28143
28181
  projects: createProjectsResource(config2),
@@ -54172,6 +54210,41 @@ function createTemplatesResource2(config2) {
54172
54210
  }
54173
54211
  };
54174
54212
  }
54213
+ function skillPath2(plugin, skill) {
54214
+ return `/skills/${encodeURIComponent(plugin)}/${encodeURIComponent(skill)}`;
54215
+ }
54216
+ function createSkillsResource2(config2) {
54217
+ return {
54218
+ /** Every Melt skill (`melt-dev:plan`, …) with its frontmatter description. Auth-only. */
54219
+ async list() {
54220
+ const { data, status } = await apiFetch2(config2, "/skills");
54221
+ if (status !== 200)
54222
+ throw new Error(data.error ?? `Failed to list skills (${status})`);
54223
+ return data.skills;
54224
+ },
54225
+ /** One skill's instructions plus the list of its reference files. */
54226
+ async get(plugin, skill, opts = {}) {
54227
+ const query = opts.client ? `?client=${encodeURIComponent(opts.client)}` : "";
54228
+ const { data, status } = await apiFetch2(config2, `${skillPath2(plugin, skill)}${query}`);
54229
+ if (status === 404)
54230
+ throw new Error(`Skill not found: ${plugin}:${skill}`);
54231
+ if (status !== 200)
54232
+ throw new Error(data.error ?? `Failed to fetch skill (${status})`);
54233
+ return data;
54234
+ },
54235
+ /** One file from the skill's folder, by the path `get` lists (`references/x.md`). */
54236
+ async getFile(plugin, skill, path22, opts = {}) {
54237
+ const params = new URLSearchParams({ path: path22 });
54238
+ if (opts.client)
54239
+ params.set("client", opts.client);
54240
+ const { data, status } = await apiFetch2(config2, `${skillPath2(plugin, skill)}/file?${params.toString()}`);
54241
+ if (status !== 200) {
54242
+ throw new Error(data.error ?? `Failed to fetch skill file (${status})`);
54243
+ }
54244
+ return data;
54245
+ }
54246
+ };
54247
+ }
54175
54248
  function createAuthResource2(config2) {
54176
54249
  return {
54177
54250
  async exchangeToken(code, redirectUri) {
@@ -55346,6 +55419,7 @@ function createMeltClient2(config2) {
55346
55419
  feedback: createFeedbackResource2(config2),
55347
55420
  coins: createCoinsResource2(config2),
55348
55421
  templates: createTemplatesResource2(config2),
55422
+ skills: createSkillsResource2(config2),
55349
55423
  auth: createAuthResource2(config2),
55350
55424
  people: createPeopleResource2(config2),
55351
55425
  projects: createProjectsResource2(config2),
@@ -56772,6 +56846,103 @@ function registerSupportEffortTools(server, getClient2) {
56772
56846
  withClientArgs(getClient2, getSupportEffort)
56773
56847
  );
56774
56848
  }
56849
+ var clientSchema = external_exports.enum(["claude", "cursor", "other"]).optional().describe(
56850
+ 'Which agent you are. Use "cursor" in Cursor; "other" (the default) for any agent without the Melt Claude plugins; "claude" only to get the file exactly as Claude Code would.'
56851
+ );
56852
+ var skillNameSchema = external_exports.string().min(1).describe(
56853
+ 'The skill, as "<plugin>:<skill>" (melt-company:verify-endpoint) or "<plugin>-<skill>" (melt-company-verify-endpoint). A leading "/" is ignored.'
56854
+ );
56855
+ var getSkillShape = { name: skillNameSchema, client: clientSchema };
56856
+ var getSkillInputSchema = external_exports.object(getSkillShape);
56857
+ var getSkillReferenceShape = {
56858
+ name: skillNameSchema,
56859
+ path: external_exports.string().min(1).describe(
56860
+ 'The file as the skill names it, relative to the skill folder, e.g. "references/standards.md" (as listed by get_skill).'
56861
+ ),
56862
+ client: clientSchema
56863
+ };
56864
+ var getSkillReferenceInputSchema = external_exports.object(getSkillReferenceShape);
56865
+ async function safeText(fn) {
56866
+ try {
56867
+ return { content: [{ type: "text", text: await fn() }] };
56868
+ } catch (err) {
56869
+ return fail(err instanceof Error ? err.message : String(err));
56870
+ }
56871
+ }
56872
+ async function resolveSkillName(client, rawName) {
56873
+ const name = rawName.trim().replace(/^\//, "");
56874
+ const colon = name.indexOf(":");
56875
+ if (colon > 0) return { plugin: name.slice(0, colon), skill: name.slice(colon + 1) };
56876
+ const match = (await client.skills.list()).find((s) => `${s.plugin}-${s.skill}` === name);
56877
+ if (!match) throw new Error(`Skill not found: ${rawName}. Call list_skills to see the names.`);
56878
+ return { plugin: match.plugin, skill: match.skill };
56879
+ }
56880
+ async function listSkills(client) {
56881
+ return safe(() => client.skills.list());
56882
+ }
56883
+ async function getSkill(client, input) {
56884
+ return safeText(async () => {
56885
+ const { plugin, skill } = await resolveSkillName(client, input.name);
56886
+ const detail = await client.skills.get(plugin, skill, { client: input.client ?? "other" });
56887
+ const references = detail.references.length ? detail.references.map((path22) => `- ${path22}`).join("\n") : "(none)";
56888
+ return [
56889
+ `# Melt skill: ${detail.name}`,
56890
+ "",
56891
+ `Follow the instructions below as if you were running the ${detail.name} skill. When they say to read a file (for example references/standards.md), fetch it with get_skill_reference (name: "${detail.name}", path: the file).`,
56892
+ "",
56893
+ `Files in this skill:
56894
+ ${references}`,
56895
+ "",
56896
+ "---",
56897
+ "",
56898
+ detail.body
56899
+ ].join("\n");
56900
+ });
56901
+ }
56902
+ async function getSkillReference(client, input) {
56903
+ return safeText(async () => {
56904
+ const { plugin, skill } = await resolveSkillName(client, input.name);
56905
+ const file2 = await client.skills.getFile(plugin, skill, input.path, {
56906
+ client: input.client ?? "other"
56907
+ });
56908
+ return file2.content;
56909
+ });
56910
+ }
56911
+ function registerSkillTools(server, getClient2) {
56912
+ server.registerTool(
56913
+ "list_skills",
56914
+ {
56915
+ title: "List Melt skills",
56916
+ description: "Lists Melt Studio's skills (the dev pipeline and audits, the PM suite, company checks like the endpoint check) with what each does. Use it when the user asks for a Melt skill you don't have installed, then load the one that fits with get_skill.",
56917
+ inputSchema: {}
56918
+ },
56919
+ withClient(getClient2, listSkills)
56920
+ );
56921
+ server.registerTool(
56922
+ "get_skill",
56923
+ {
56924
+ title: "Load a Melt skill",
56925
+ description: `Loads a Melt skill's full instructions. Treat what it returns as the skill itself: follow the instructions exactly, step by step, as if the skill were installed. When they say to read a file ("read references/x.md"), fetch it with get_skill_reference instead of looking on disk. Pass client: "cursor" when running in Cursor.`,
56926
+ inputSchema: getSkillShape
56927
+ },
56928
+ withClientArgs(
56929
+ getClient2,
56930
+ (client, args) => getSkill(client, args)
56931
+ )
56932
+ );
56933
+ server.registerTool(
56934
+ "get_skill_reference",
56935
+ {
56936
+ title: "Read a file from a Melt skill",
56937
+ description: `Returns one of a Melt skill's reference files (a checklist, template or standards doc) as markdown. Use it whenever a skill loaded with get_skill says to read a file like "references/standards.md"; the files are not on disk. Follow its contents as part of the skill.`,
56938
+ inputSchema: getSkillReferenceShape
56939
+ },
56940
+ withClientArgs(
56941
+ getClient2,
56942
+ (client, args) => getSkillReference(client, args)
56943
+ )
56944
+ );
56945
+ }
56775
56946
  var VERSION = "0.0.0";
56776
56947
  function createMcpServer(clientOrProvider) {
56777
56948
  const getClient2 = typeof clientOrProvider === "function" ? clientOrProvider : () => Promise.resolve(clientOrProvider);
@@ -56791,6 +56962,7 @@ function createMcpServer(clientOrProvider) {
56791
56962
  registerDailyPlanTools(server, getClient2);
56792
56963
  registerEndpointCheckTools(server, getClient2);
56793
56964
  registerSupportEffortTools(server, getClient2);
56965
+ registerSkillTools(server, getClient2);
56794
56966
  return server;
56795
56967
  }
56796
56968
  async function startServer() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/meltctl",
3
- "version": "5.26.0",
3
+ "version": "5.27.0",
4
4
  "description": "AI-first development tooling for Melt teams — companion CLI for the org-distributed Claude Code dev skills",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",