@zhixuan92/multi-model-agent 4.7.10 → 4.7.11

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 (66) hide show
  1. package/README.md +1 -2
  2. package/dist/cli/serve.d.ts.map +1 -1
  3. package/dist/cli/serve.js +5 -6
  4. package/dist/cli/serve.js.map +1 -1
  5. package/dist/cli/sync-skills.d.ts +1 -1
  6. package/dist/cli/sync-skills.d.ts.map +1 -1
  7. package/dist/cli/sync-skills.js +3 -3
  8. package/dist/cli/sync-skills.js.map +1 -1
  9. package/dist/http/handlers/introspection/health.d.ts +2 -2
  10. package/dist/http/handlers/introspection/health.d.ts.map +1 -1
  11. package/dist/http/server.d.ts +1 -1
  12. package/dist/http/server.d.ts.map +1 -1
  13. package/dist/http/server.js +2 -7
  14. package/dist/http/server.js.map +1 -1
  15. package/dist/skill-install/discover.d.ts +29 -0
  16. package/dist/skill-install/discover.d.ts.map +1 -0
  17. package/dist/skill-install/discover.js +102 -0
  18. package/dist/skill-install/discover.js.map +1 -0
  19. package/dist/skill-install/include-utils.d.ts +27 -0
  20. package/dist/skill-install/include-utils.d.ts.map +1 -0
  21. package/dist/skill-install/include-utils.js +90 -0
  22. package/dist/skill-install/include-utils.js.map +1 -0
  23. package/dist/skill-install/manifest.d.ts +90 -0
  24. package/dist/skill-install/manifest.d.ts.map +1 -0
  25. package/dist/skill-install/manifest.js +228 -0
  26. package/dist/skill-install/manifest.js.map +1 -0
  27. package/dist/skill-install/skill-installer-common.d.ts +48 -0
  28. package/dist/skill-install/skill-installer-common.d.ts.map +1 -0
  29. package/dist/skill-install/skill-installer-common.js +195 -0
  30. package/dist/skill-install/skill-installer-common.js.map +1 -0
  31. package/dist/skill-install/skill-installers/claude-code.d.ts +43 -0
  32. package/dist/skill-install/skill-installers/claude-code.d.ts.map +1 -0
  33. package/dist/skill-install/skill-installers/claude-code.js +65 -0
  34. package/dist/skill-install/skill-installers/claude-code.js.map +1 -0
  35. package/dist/skill-install/skill-installers/codex-cli.d.ts +27 -0
  36. package/dist/skill-install/skill-installers/codex-cli.d.ts.map +1 -0
  37. package/dist/skill-install/skill-installers/codex-cli.js +84 -0
  38. package/dist/skill-install/skill-installers/codex-cli.js.map +1 -0
  39. package/dist/skill-install/skill-installers/cursor.d.ts +72 -0
  40. package/dist/skill-install/skill-installers/cursor.d.ts.map +1 -0
  41. package/dist/skill-install/skill-installers/cursor.js +81 -0
  42. package/dist/skill-install/skill-installers/cursor.js.map +1 -0
  43. package/dist/skill-install/skill-installers/gemini-cli.d.ts +50 -0
  44. package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +1 -0
  45. package/dist/skill-install/skill-installers/gemini-cli.js +72 -0
  46. package/dist/skill-install/skill-installers/gemini-cli.js.map +1 -0
  47. package/dist/skill-install/skill-manifest-sync.d.ts +11 -0
  48. package/dist/skill-install/skill-manifest-sync.d.ts.map +1 -0
  49. package/dist/skill-install/skill-manifest-sync.js +65 -0
  50. package/dist/skill-install/skill-manifest-sync.js.map +1 -0
  51. package/dist/skills/mma-audit/SKILL.md +1 -1
  52. package/dist/skills/mma-context-blocks/SKILL.md +1 -1
  53. package/dist/skills/mma-debug/SKILL.md +1 -1
  54. package/dist/skills/mma-delegate/SKILL.md +1 -1
  55. package/dist/skills/mma-execute-plan/SKILL.md +1 -1
  56. package/dist/skills/mma-explore/SKILL.md +1 -1
  57. package/dist/skills/mma-investigate/SKILL.md +1 -1
  58. package/dist/skills/mma-research/SKILL.md +1 -1
  59. package/dist/skills/mma-retry/SKILL.md +1 -1
  60. package/dist/skills/mma-review/SKILL.md +1 -1
  61. package/dist/skills/multi-model-agent/SKILL.md +1 -1
  62. package/package.json +2 -2
  63. package/dist/http/handlers/introspection/tools-list.d.ts +0 -9
  64. package/dist/http/handlers/introspection/tools-list.d.ts.map +0 -1
  65. package/dist/http/handlers/introspection/tools-list.js +0 -28
  66. package/dist/http/handlers/introspection/tools-list.js.map +0 -1
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Claude Code skill writer for install-skill.
3
+ *
4
+ * Writes each skill's SKILL.md to `<homeDir>/.claude/skills/<skillName>/SKILL.md`.
5
+ *
6
+ * Before writing, inlines any `@include _shared/<file>.md` directives found in
7
+ * the content. The directive line is replaced with the full content of the
8
+ * corresponding shared file sourced from `<skillsRoot>/_shared/<file>.md`.
9
+ * The `@include` directive is NOT preserved in the written file.
10
+ *
11
+ * If a referenced shared file is missing (ENOENT):
12
+ * - A warning is logged to stderr.
13
+ * - The include line is removed from the output (not preserved).
14
+ * - Processing continues for remaining content.
15
+ *
16
+ * @module
17
+ */
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ import { inlineIncludes } from '../include-utils.js';
21
+ /**
22
+ * Write (or overwrite) the SKILL.md file for a Claude Code skill.
23
+ *
24
+ * Target path: `<homeDir>/.claude/skills/<skillName>/SKILL.md`
25
+ *
26
+ * @param opts Installation options (see `ClaudeCodeInstallOpts`).
27
+ */
28
+ export function installClaudeCode(opts) {
29
+ const { skillName, content, homeDir, skillsRoot } = opts;
30
+ // Inline @include directives before writing
31
+ const inlinedContent = inlineIncludes('Claude Code skill writer', content, skillsRoot);
32
+ // Determine target path: <homeDir>/.claude/skills/<skillName>/SKILL.md
33
+ const skillDir = path.join(homeDir, '.claude', 'skills', skillName);
34
+ fs.mkdirSync(skillDir, { recursive: true });
35
+ fs.writeFileSync(path.join(skillDir, 'SKILL.md'), inlinedContent, 'utf-8');
36
+ }
37
+ /**
38
+ * Uninstall a Claude Code skill by removing its directory.
39
+ *
40
+ * Target: `<homeDir>/.claude/skills/<skillName>/`
41
+ *
42
+ * Security: `skillName` is validated against the expected skills directory
43
+ * boundary to prevent path traversal (e.g. `../other-dir`). If `skillName`
44
+ * resolves outside the skills directory, the function is a no-op.
45
+ *
46
+ * This is also a no-op when the directory does not exist (no error is thrown).
47
+ *
48
+ * @param skillName Name of the skill to uninstall.
49
+ * @param homeDir Home directory where the skill directory lives.
50
+ */
51
+ export function uninstallClaudeCode(skillName, homeDir) {
52
+ const skillsBase = path.resolve(homeDir, '.claude', 'skills');
53
+ // Security: validate skillName does not escape the skills directory.
54
+ // Normalize skillName and verify the resolved path stays within the base.
55
+ const normalizedName = path.normalize(skillName);
56
+ const resolvedSkillDir = path.resolve(skillsBase, normalizedName);
57
+ const baseResolved = skillsBase + path.sep;
58
+ if (!resolvedSkillDir.startsWith(baseResolved)) {
59
+ // skillName traversal attempt — no-op rather than throwing, matching
60
+ // the "no error when directory does not exist" behaviour.
61
+ return;
62
+ }
63
+ fs.rmSync(resolvedSkillDir, { recursive: true, force: true });
64
+ }
65
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAsBrD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAEzD,4CAA4C;IAC5C,MAAM,cAAc,GAAG,cAAc,CAAC,0BAA0B,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAEvF,uEAAuE;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpE,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,OAAe;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE9D,qEAAqE;IACrE,0EAA0E;IAC1E,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;IAC3C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,qEAAqE;QACrE,0DAA0D;QAC1D,OAAO;IACT,CAAC;IAED,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface CodexCliInstallOpts {
2
+ /** Human-readable name of the skill (used in file path). */
3
+ skillName: string;
4
+ /** Raw skill content, possibly containing @include directives. */
5
+ content: string;
6
+ /**
7
+ * Home directory — replaces `os.homedir()` in all file operations.
8
+ * Must NOT default to `os.homedir()`.
9
+ */
10
+ homeDir: string;
11
+ /** Root of the skills directory for @include resolution. */
12
+ skillsRoot: string;
13
+ }
14
+ /**
15
+ * Write (or overwrite) the SKILL.md file for a Codex CLI skill.
16
+ *
17
+ * Target path: `<homeDir>/.codex/skills/<skillName>/SKILL.md`
18
+ */
19
+ export declare function installCodexCli(opts: CodexCliInstallOpts): void;
20
+ /**
21
+ * Uninstall a Codex CLI skill by removing its directory.
22
+ *
23
+ * This is a no-op when the directory does not exist or when `skillName` would
24
+ * escape the Codex skills directory.
25
+ */
26
+ export declare function uninstallCodexCli(skillName: string, homeDir: string): void;
27
+ //# sourceMappingURL=codex-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-cli.d.ts","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/codex-cli.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAuCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAW/D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK1E"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Codex CLI skill writer for install-skill.
3
+ *
4
+ * Writes each skill's SKILL.md to `<homeDir>/.codex/skills/<skillName>/SKILL.md`.
5
+ * Codex discovers skills from that directory on the next session start. Existing
6
+ * `AGENTS.md` instructions are user-owned and are not modified by this writer.
7
+ *
8
+ * Before writing, any `@include _shared/<file>.md` directives are inlined using
9
+ * the shared include utility. Missing shared files are warned about and omitted,
10
+ * matching the other client writers.
11
+ *
12
+ * @module
13
+ */
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { inlineIncludes } from '../include-utils.js';
17
+ const LEGACY_MANAGED_BEGIN = '<!-- multi-model-agent:BEGIN -->';
18
+ const LEGACY_MANAGED_END = '<!-- multi-model-agent:END -->';
19
+ function codexSkillsBase(homeDir) {
20
+ return path.resolve(homeDir, '.codex', 'skills');
21
+ }
22
+ function resolveSkillDir(homeDir, skillName) {
23
+ const base = codexSkillsBase(homeDir);
24
+ const resolved = path.resolve(base, path.normalize(skillName));
25
+ if (!resolved.startsWith(base + path.sep))
26
+ return null;
27
+ return resolved;
28
+ }
29
+ function removeLegacyManagedAgentsBlock(homeDir) {
30
+ const agentsPath = path.join(homeDir, '.codex', 'AGENTS.md');
31
+ let content;
32
+ try {
33
+ content = fs.readFileSync(agentsPath, 'utf-8');
34
+ }
35
+ catch (err) {
36
+ if (err.code === 'ENOENT')
37
+ return;
38
+ throw err;
39
+ }
40
+ const beginIdx = content.indexOf(LEGACY_MANAGED_BEGIN);
41
+ const endIdx = content.indexOf(LEGACY_MANAGED_END);
42
+ if (beginIdx === -1 || endIdx === -1 || beginIdx > endIdx)
43
+ return;
44
+ const suffixStart = endIdx + LEGACY_MANAGED_END.length;
45
+ const prefix = content.slice(0, beginIdx);
46
+ const suffix = content.slice(suffixStart).replace(/^\n+/, '');
47
+ const nextContent = `${prefix}${suffix}`;
48
+ if (nextContent.trim() === '') {
49
+ fs.unlinkSync(agentsPath);
50
+ }
51
+ else {
52
+ fs.writeFileSync(agentsPath, nextContent, 'utf-8');
53
+ }
54
+ }
55
+ /**
56
+ * Write (or overwrite) the SKILL.md file for a Codex CLI skill.
57
+ *
58
+ * Target path: `<homeDir>/.codex/skills/<skillName>/SKILL.md`
59
+ */
60
+ export function installCodexCli(opts) {
61
+ const { skillName, content, homeDir, skillsRoot } = opts;
62
+ const skillDir = resolveSkillDir(homeDir, skillName);
63
+ if (skillDir === null) {
64
+ throw new Error(`Invalid Codex CLI skill name: ${skillName}`);
65
+ }
66
+ removeLegacyManagedAgentsBlock(homeDir);
67
+ const inlinedContent = inlineIncludes('Codex CLI skill writer', content, skillsRoot);
68
+ fs.mkdirSync(skillDir, { recursive: true });
69
+ fs.writeFileSync(path.join(skillDir, 'SKILL.md'), inlinedContent, 'utf-8');
70
+ }
71
+ /**
72
+ * Uninstall a Codex CLI skill by removing its directory.
73
+ *
74
+ * This is a no-op when the directory does not exist or when `skillName` would
75
+ * escape the Codex skills directory.
76
+ */
77
+ export function uninstallCodexCli(skillName, homeDir) {
78
+ removeLegacyManagedAgentsBlock(homeDir);
79
+ const skillDir = resolveSkillDir(homeDir, skillName);
80
+ if (skillDir === null)
81
+ return;
82
+ fs.rmSync(skillDir, { recursive: true, force: true });
83
+ }
84
+ //# sourceMappingURL=codex-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-cli.js","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/codex-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,oBAAoB,GAAG,kCAAkC,CAAC;AAChE,MAAM,kBAAkB,GAAG,gCAAgC,CAAC;AAgB5D,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,SAAiB;IACzD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,8BAA8B,CAAC,OAAe;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC7D,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC7D,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,MAAM;QAAE,OAAO;IAElE,MAAM,WAAW,GAAG,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IAEzC,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACzD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,cAAc,CAAC,wBAAwB,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACrF,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,OAAe;IAClE,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO;IAC9B,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Options for installing a Cursor skill.
3
+ *
4
+ * NOTE: `homeDir` is accepted for API parity with other skill writers
5
+ * (Claude Code, Gemini CLI, etc.) but is intentionally not used by this
6
+ * writer. The Cursor rules target path is always CWD-relative under
7
+ * `<cwd>/.cursor/rules/`, not homeDir-relative. This is intentional to
8
+ * keep Cursor rules scoped to the project directory.
9
+ */
10
+ export interface CursorInstallOpts {
11
+ /**
12
+ * Raw skill content. May contain `@include _shared/<file>.md` directives
13
+ * which are inlined before writing.
14
+ */
15
+ content: string;
16
+ /**
17
+ * Working directory — replaces `process.cwd()`.
18
+ * Used to construct the CWD-relative target path:
19
+ * `<cwd>/.cursor/rules/multi-model-agent.mdc`
20
+ */
21
+ cwd: string;
22
+ /**
23
+ * Home directory. Accepted for API signature compatibility with other
24
+ * skill writers, but NOT used by this writer. Cursor rules are always
25
+ * written relative to `cwd`, not `homeDir`.
26
+ */
27
+ homeDir: string;
28
+ /**
29
+ * Where shared files live. The writer reads `<skillsRoot>/_shared/<path>`
30
+ * when inlining `@include` directives.
31
+ */
32
+ skillsRoot: string;
33
+ /**
34
+ * If true, overwrite the existing file. If false (default), skip writing
35
+ * when the file already exists.
36
+ */
37
+ force?: boolean;
38
+ }
39
+ /**
40
+ * Result of `installCursor`.
41
+ */
42
+ export interface CursorInstallResult {
43
+ /**
44
+ * `true` if the file was written, `false` if it was skipped because it
45
+ * already exists and `force` was not set.
46
+ */
47
+ written: boolean;
48
+ /** The full path that was (or would have been) written. */
49
+ targetPath: string;
50
+ }
51
+ /**
52
+ * Install the multi-model-agent skill for Cursor.
53
+ *
54
+ * - Target path is `<cwd>/.cursor/rules/multi-model-agent.mdc` (CWD-relative).
55
+ * - Creates `<cwd>/.cursor/rules/` if it does not exist.
56
+ * - Inlines `@include` directives before writing (see `inlineIncludes`).
57
+ * - If the file already exists and `force` is not set, skips writing and
58
+ * returns `written: false`.
59
+ *
60
+ * @param opts Installation options (see `CursorInstallOpts`).
61
+ */
62
+ export declare function installCursor(opts: CursorInstallOpts): CursorInstallResult;
63
+ /**
64
+ * Uninstall the multi-model-agent Cursor skill.
65
+ *
66
+ * Removes `<cwd>/.cursor/rules/multi-model-agent.mdc`.
67
+ * This is a no-op when the file does not exist (no error is thrown).
68
+ *
69
+ * @param cwd Working directory (replaces `process.cwd()`).
70
+ */
71
+ export declare function uninstallCursor(cwd: string): void;
72
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/cursor.ts"],"names":[],"mappings":"AA8BA;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAmB1E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAmBjD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Cursor skill writer.
3
+ *
4
+ * Writes the skill content to `<cwd>/.cursor/rules/multi-model-agent.mdc`.
5
+ *
6
+ * Before writing, inlines any `@include _shared/<file>.md` directives found in
7
+ * the content. The directive line is replaced with the full content of
8
+ * the corresponding shared file sourced from `<skillsRoot>/_shared/<path>`.
9
+ * The `@include` directive is NOT preserved in the written file.
10
+ *
11
+ * If a referenced shared file is missing (ENOENT):
12
+ * - A warning is logged to stderr.
13
+ * - The include line is removed from the output (not preserved).
14
+ * - Processing continues for remaining directives.
15
+ *
16
+ * Security constraints on `@include` directives:
17
+ * - Only paths beginning with `_shared/` are accepted.
18
+ * - The resolved path must stay within `<skillsRoot>/_shared/`.
19
+ * Path traversal attempts (e.g. `_shared/../secrets.txt`) are rejected
20
+ * with a warning and the directive line is dropped.
21
+ * - Non-`_shared/` paths are rejected with a warning and the directive
22
+ * line is dropped.
23
+ *
24
+ * @module
25
+ */
26
+ import fs from 'node:fs';
27
+ import path from 'node:path';
28
+ import { inlineIncludes } from '../include-utils.js';
29
+ /**
30
+ * Install the multi-model-agent skill for Cursor.
31
+ *
32
+ * - Target path is `<cwd>/.cursor/rules/multi-model-agent.mdc` (CWD-relative).
33
+ * - Creates `<cwd>/.cursor/rules/` if it does not exist.
34
+ * - Inlines `@include` directives before writing (see `inlineIncludes`).
35
+ * - If the file already exists and `force` is not set, skips writing and
36
+ * returns `written: false`.
37
+ *
38
+ * @param opts Installation options (see `CursorInstallOpts`).
39
+ */
40
+ export function installCursor(opts) {
41
+ const { content, cwd, skillsRoot, force } = opts;
42
+ const targetPath = path.join(cwd, '.cursor', 'rules', 'multi-model-agent.mdc');
43
+ if (!force && fs.existsSync(targetPath)) {
44
+ process.stderr.write(`Warning: Cursor skill writer: file already exists: ${targetPath} — skipping (use force: true to overwrite)\n`);
45
+ return { written: false, targetPath };
46
+ }
47
+ const rulesDir = path.join(cwd, '.cursor', 'rules');
48
+ fs.mkdirSync(rulesDir, { recursive: true, mode: 0o700 });
49
+ const finalContent = inlineIncludes('Cursor skill writer', content, skillsRoot);
50
+ fs.writeFileSync(targetPath, finalContent, 'utf-8');
51
+ return { written: true, targetPath };
52
+ }
53
+ /**
54
+ * Uninstall the multi-model-agent Cursor skill.
55
+ *
56
+ * Removes `<cwd>/.cursor/rules/multi-model-agent.mdc`.
57
+ * This is a no-op when the file does not exist (no error is thrown).
58
+ *
59
+ * @param cwd Working directory (replaces `process.cwd()`).
60
+ */
61
+ export function uninstallCursor(cwd) {
62
+ const targetPath = path.join(cwd, '.cursor', 'rules', 'multi-model-agent.mdc');
63
+ // Only remove the file if it exists and is a file (not a directory).
64
+ // This is a no-op when the path does not exist.
65
+ try {
66
+ const stat = fs.statSync(targetPath);
67
+ if (stat.isFile()) {
68
+ fs.unlinkSync(targetPath);
69
+ }
70
+ // If it's a directory or symlink to directory, do nothing — the brief
71
+ // specifies removing a file, not a directory tree.
72
+ }
73
+ catch (err) {
74
+ const nodeErr = err;
75
+ // ENOENT means the file doesn't exist — that's fine, we were asked to remove it
76
+ if (nodeErr.code !== 'ENOENT') {
77
+ throw err;
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAsDrD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAEjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC;IAE/E,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sDAAsD,UAAU,8CAA8C,CAC/G,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACpD,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEzD,MAAM,YAAY,GAAG,cAAc,CAAC,qBAAqB,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAEpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC;IAE/E,qEAAqE;IACrE,gDAAgD;IAChD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QACD,sEAAsE;QACtE,mDAAmD;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAA4B,CAAC;QAC7C,gFAAgF;QAChF,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Options for installing a skill via the Gemini CLI writer.
3
+ */
4
+ export interface GeminiCliInstallOpts {
5
+ /** Skill name (currently informational; writes always go to multi-model-agent extension). */
6
+ skillName: string;
7
+ /**
8
+ * Raw SKILL.md content. May contain `@include _shared/<file>.md` directives
9
+ * which are inlined before writing.
10
+ */
11
+ content: string;
12
+ /**
13
+ * Version string for the extension manifest's `version` field.
14
+ */
15
+ skillVersion: string;
16
+ /**
17
+ * The "home directory" that replaces `os.homedir()`.
18
+ * Must NOT default to `os.homedir()` — always required explicitly.
19
+ */
20
+ homeDir: string;
21
+ /**
22
+ * Where shared files live. The writer reads `<skillsRoot>/_shared/<file>.md`
23
+ * when inlining `@include` directives.
24
+ */
25
+ skillsRoot: string;
26
+ }
27
+ /**
28
+ * Install a skill to the Gemini CLI extensions directory.
29
+ *
30
+ * Writes two files into `<homeDir>/.gemini/extensions/multi-model-agent/`:
31
+ * 1. `gemini-extension.json` — the extension manifest
32
+ * 2. `SKILL.md` — the skill content with @include directives inlined
33
+ *
34
+ * The directory (and any parent directories) are created with mode `0o700`.
35
+ * Calling this function multiple times overwrites the previous installation
36
+ * (idempotent).
37
+ *
38
+ * @param opts Installation options (see `GeminiCliInstallOpts`).
39
+ */
40
+ export declare function installGeminiCli(opts: GeminiCliInstallOpts): void;
41
+ /**
42
+ * Uninstall the multi-model-agent Gemini CLI extension.
43
+ *
44
+ * Recursively removes `<homeDir>/.gemini/extensions/multi-model-agent/`.
45
+ * This is a no-op when the directory does not exist (no error is thrown).
46
+ *
47
+ * @param homeDir The "home directory" that replaces `os.homedir()`.
48
+ */
49
+ export declare function uninstallGeminiCli(homeDir: string): void;
50
+ //# sourceMappingURL=gemini-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.d.ts","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/gemini-cli.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAuBjE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKxD"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Gemini CLI skill writer.
3
+ *
4
+ * Writes to `<homeDir>/.gemini/extensions/multi-model-agent/`:
5
+ * - `gemini-extension.json` — extension manifest
6
+ * - `SKILL.md` — skill content (with @include directives inlined)
7
+ *
8
+ * The extension is always named `multi-model-agent` regardless of `skillName`
9
+ * (the extension loads whichever skill files are provided). This is a
10
+ * judgment call because the Gemini CLI extension format is not fully
11
+ * standardized; a minimal JSON schema is used.
12
+ *
13
+ * Before writing SKILL.md, any `@include _shared/<file>.md` directive lines
14
+ * are replaced via the shared `inlineIncludes` helper (the same one
15
+ * Claude/Codex/Cursor use). That helper enforces the `_shared/` prefix,
16
+ * rejects path traversal, suppresses only ENOENT (missing file → warn + drop),
17
+ * and re-throws other I/O errors.
18
+ *
19
+ * @module
20
+ */
21
+ import fs from 'node:fs';
22
+ import path from 'node:path';
23
+ import { inlineIncludes } from '../include-utils.js';
24
+ /**
25
+ * Install a skill to the Gemini CLI extensions directory.
26
+ *
27
+ * Writes two files into `<homeDir>/.gemini/extensions/multi-model-agent/`:
28
+ * 1. `gemini-extension.json` — the extension manifest
29
+ * 2. `SKILL.md` — the skill content with @include directives inlined
30
+ *
31
+ * The directory (and any parent directories) are created with mode `0o700`.
32
+ * Calling this function multiple times overwrites the previous installation
33
+ * (idempotent).
34
+ *
35
+ * @param opts Installation options (see `GeminiCliInstallOpts`).
36
+ */
37
+ export function installGeminiCli(opts) {
38
+ const { skillName: _skillName, content, skillVersion, homeDir, skillsRoot } = opts;
39
+ const extDir = path.join(homeDir, '.gemini', 'extensions', 'multi-model-agent');
40
+ fs.mkdirSync(extDir, { recursive: true, mode: 0o700 });
41
+ // Write the extension manifest.
42
+ // Shape is a minimal reasonable schema; Gemini CLI extension format is not
43
+ // fully standardized, so we document this judgment call.
44
+ const manifest = {
45
+ name: 'multi-model-agent',
46
+ version: skillVersion,
47
+ description: 'multi-model-agent skills for Gemini CLI',
48
+ schemaVersion: '1.0',
49
+ contextFiles: ['SKILL.md'],
50
+ };
51
+ const manifestPath = path.join(extDir, 'gemini-extension.json');
52
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
53
+ // Write the skill content with @include directives inlined.
54
+ const finalContent = inlineIncludes('Gemini CLI skill writer', content, skillsRoot);
55
+ const skillPath = path.join(extDir, 'SKILL.md');
56
+ fs.writeFileSync(skillPath, finalContent, 'utf-8');
57
+ }
58
+ /**
59
+ * Uninstall the multi-model-agent Gemini CLI extension.
60
+ *
61
+ * Recursively removes `<homeDir>/.gemini/extensions/multi-model-agent/`.
62
+ * This is a no-op when the directory does not exist (no error is thrown).
63
+ *
64
+ * @param homeDir The "home directory" that replaces `os.homedir()`.
65
+ */
66
+ export function uninstallGeminiCli(homeDir) {
67
+ const extDir = path.join(homeDir, '.gemini', 'extensions', 'multi-model-agent');
68
+ if (fs.existsSync(extDir)) {
69
+ fs.rmSync(extDir, { recursive: true, force: true });
70
+ }
71
+ }
72
+ //# sourceMappingURL=gemini-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../../src/skill-install/skill-installers/gemini-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA6BrD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAEnF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAChF,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEvD,gCAAgC;IAChC,2EAA2E;IAC3E,yDAAyD;IACzD,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,yCAAyC;QACtD,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,CAAC,UAAU,CAAC;KAC3B,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAElF,4DAA4D;IAC5D,MAAM,YAAY,GAAG,cAAc,CAAC,yBAAyB,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAChF,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Client } from './manifest.js';
2
+ export interface DriftEntry {
3
+ skill: string;
4
+ client: Client;
5
+ issue: 'missing' | 'outdated' | 'orphan';
6
+ }
7
+ export interface SkillManifestSync {
8
+ driftReport(): DriftEntry[];
9
+ }
10
+ export declare function makeSkillManifestSync(perClientInstallDirs: Partial<Record<Client, string>>): SkillManifestSync;
11
+ //# sourceMappingURL=skill-manifest-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-manifest-sync.d.ts","sourceRoot":"","sources":["../../src/skill-install/skill-manifest-sync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,IAAI,UAAU,EAAE,CAAC;CAC7B;AAcD,wBAAgB,qBAAqB,CAAC,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,iBAAiB,CAuC9G"}
@@ -0,0 +1,65 @@
1
+ import { readdirSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { SUPPORTED_SKILLS, readSkillContent } from './discover.js';
4
+ import matter from 'gray-matter';
5
+ function canonicalVersion(skillName) {
6
+ const content = readSkillContent(skillName);
7
+ if (content === null)
8
+ return null;
9
+ try {
10
+ const parsed = matter(content);
11
+ const v = parsed.data['version'];
12
+ return typeof v === 'string' ? v : null;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ export function makeSkillManifestSync(perClientInstallDirs) {
19
+ return {
20
+ driftReport() {
21
+ const drift = [];
22
+ const supported = new Set(SUPPORTED_SKILLS);
23
+ for (const [client, dir] of Object.entries(perClientInstallDirs)) {
24
+ let entries;
25
+ try {
26
+ entries = readdirSync(dir);
27
+ }
28
+ catch {
29
+ continue;
30
+ }
31
+ const present = new Set(entries.filter(n => n.startsWith('mma-') || n === 'multi-model-agent'));
32
+ for (const exp of supported) {
33
+ if (!present.has(exp))
34
+ drift.push({ skill: exp, client: client, issue: 'missing' });
35
+ }
36
+ for (const got of present) {
37
+ if (!supported.has(got)) {
38
+ drift.push({ skill: got, client: client, issue: 'orphan' });
39
+ }
40
+ }
41
+ for (const skill of present) {
42
+ if (!supported.has(skill))
43
+ continue;
44
+ const canonVer = canonicalVersion(skill);
45
+ if (canonVer === null)
46
+ continue;
47
+ const installedPath = join(dir, skill, 'SKILL.md');
48
+ try {
49
+ const installedContent = readFileSync(installedPath, 'utf-8');
50
+ const parsed = matter(installedContent);
51
+ const installedVer = parsed.data['version'];
52
+ if (typeof installedVer === 'string' && installedVer !== canonVer) {
53
+ drift.push({ skill, client: client, issue: 'outdated' });
54
+ }
55
+ }
56
+ catch {
57
+ // skip outdated check if installed SKILL.md is unreadable
58
+ }
59
+ }
60
+ }
61
+ return drift;
62
+ },
63
+ };
64
+ }
65
+ //# sourceMappingURL=skill-manifest-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-manifest-sync.js","sourceRoot":"","sources":["../../src/skill-install/skill-manifest-sync.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ when_to_use: >-
12
12
  (superpowers:dispatching-parallel-agents, /security-review) points at one AND
13
13
  mmagent is running. Audit on PROSE/SPEC docs — use mma-review for source code.
14
14
  Audit a CODE-EXECUTION PLAN against the codebase — use subtype=plan.
15
- version: 4.7.10
15
+ version: 4.7.11
16
16
  ---
17
17
 
18
18
  # mma-audit
@@ -12,7 +12,7 @@ when_to_use: >-
12
12
  Register once here, then pass the ID via `contextBlockIds` on mma-delegate /
13
13
  mma-execute-plan / mma-audit / mma-review / mma-debug / mma-investigate.
14
14
  Cheaper and faster than inlining the same content N times.
15
- version: 4.7.10
15
+ version: 4.7.11
16
16
  ---
17
17
 
18
18
  # mma-context-blocks
@@ -10,7 +10,7 @@ when_to_use: >-
10
10
  read files, reproduce, trace — OR a methodology skill
11
11
  (superpowers:systematic-debugging) points at the investigation step. Delegate
12
12
  the read/reproduce/trace; the main agent stays on the hypothesis and the fix.
13
- version: 4.7.10
13
+ version: 4.7.11
14
14
  ---
15
15
 
16
16
  # mma-debug
@@ -11,7 +11,7 @@ when_to_use: >-
11
11
  and keep main context free. If a plan file exists → use mma-execute-plan. If
12
12
  the task is audit / review / verify / debug / investigate → use the matching
13
13
  specialized skill.
14
- version: 4.7.10
14
+ version: 4.7.11
15
15
  ---
16
16
 
17
17
  # mma-delegate
@@ -10,7 +10,7 @@ when_to_use: >-
10
10
  superpowers:subagent-driven-development / superpowers:executing-plans —
11
11
  workers are cheaper and don't pollute main context. Task descriptors must
12
12
  match plan headings verbatim.
13
- version: 4.7.10
13
+ version: 4.7.11
14
14
  ---
15
15
 
16
16
  # mma-execute-plan
@@ -12,7 +12,7 @@ when_to_use: >-
12
12
  out mma-investigate (internal) + mma-research (external) in parallel and
13
13
  synthesise the results yourself. DO NOT use for convergent single-answer
14
14
  questions — those are mma-investigate.
15
- version: 4.7.10
15
+ version: 4.7.11
16
16
  ---
17
17
 
18
18
  # mma-explore
@@ -12,7 +12,7 @@ when_to_use: >-
12
12
  git-history queries. OR you are about to read 3+ files / run any grep in main
13
13
  context — that's the inline-labor-leakage anti-pattern (AP2); delegate to this
14
14
  skill instead.
15
- version: 4.7.10
15
+ version: 4.7.11
16
16
  ---
17
17
 
18
18
  # mma-investigate