@luanpdd/kit-mcp 1.14.0 → 1.15.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 (34) hide show
  1. package/README.md +4 -0
  2. package/kit/COMPATIBILITY.md +65 -0
  3. package/kit/agents/ai-mutation-tester.md +1 -11
  4. package/kit/agents/burn-rate-forecaster.md +1 -9
  5. package/kit/agents/cascading-failures-auditor.md +1 -9
  6. package/kit/agents/golden-signals-instrumenter.md +1 -11
  7. package/kit/agents/incident-investigator.md +1 -9
  8. package/kit/agents/legacy-characterizer.md +1 -11
  9. package/kit/agents/load-shedding-instrumenter.md +1 -9
  10. package/kit/agents/observability-coverage-auditor.md +1 -11
  11. package/kit/agents/observability-instrumenter.md +1 -11
  12. package/kit/agents/omm-auditor.md +1 -9
  13. package/kit/agents/payload-capture-instrumenter.md +1 -11
  14. package/kit/agents/postmortem-writer.md +1 -11
  15. package/kit/agents/prr-conductor.md +1 -11
  16. package/kit/agents/refactor-safety-auditor.md +1 -11
  17. package/kit/agents/release-pipeline-auditor.md +1 -9
  18. package/kit/agents/seam-finder.md +1 -9
  19. package/kit/agents/shotgun-surgery-detector.md +1 -11
  20. package/kit/agents/slo-engineer.md +1 -9
  21. package/kit/agents/storytelling-analyst.md +1 -11
  22. package/kit/agents/supabase-architect.md +1 -9
  23. package/kit/agents/supabase-auth-bootstrapper.md +1 -11
  24. package/kit/agents/supabase-edge-fn-writer.md +1 -11
  25. package/kit/agents/supabase-migration-writer.md +1 -9
  26. package/kit/agents/supabase-realtime-implementer.md +1 -9
  27. package/kit/agents/supabase-rls-writer.md +1 -9
  28. package/kit/agents/supabase-storage-implementer.md +1 -9
  29. package/kit/agents/toil-auditor.md +1 -11
  30. package/kit/file-manifest.json +251 -250
  31. package/package.json +2 -2
  32. package/src/cli/index.js +28 -12
  33. package/src/core/manifest-verify.js +5 -1
  34. package/src/mcp-server/index.js +14 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luanpdd/kit-mcp",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "Generic infrastructure to ship YOUR personal kit of agents/commands/skills as an MCP server, with cross-IDE sync (Claude Code, Cursor, Codex, Gemini, Windsurf, Antigravity, Copilot, Trae).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,7 +44,7 @@
44
44
  "test": "node test/run.mjs test/unit",
45
45
  "test:integration": "node test/run.mjs test/integration",
46
46
  "test:all": "node test/run.mjs test",
47
- "prepublishOnly": "node test/run.mjs test/unit && node test/run.mjs test/integration"
47
+ "prepublishOnly": "node scripts/regen-manifest.js && node scripts/update-readme-counts.js && node test/run.mjs test/unit && node test/run.mjs test/integration"
48
48
  },
49
49
  "dependencies": {
50
50
  "@inquirer/prompts": "^8.4.2",
package/src/cli/index.js CHANGED
@@ -154,20 +154,36 @@ function slim(x) {
154
154
  return { kind: x.kind, name: x.name, description: summarize(x.description) };
155
155
  }
156
156
 
157
+ // PERF-15-01: terse variant — paridade com mcp-server slimTerse. CLI flag --terse
158
+ // controla seleção. Mantém o mesmo shape {kind, name} para programmatic consumers
159
+ // que parseiam --json output (consistência cross-surface).
160
+ function slimTerse(x) {
161
+ return { kind: x.kind, name: x.name };
162
+ }
163
+
157
164
  // --- kit ---
158
165
  const kit = program.command('kit').description('Browse the canonical kit.');
159
- kit.command('list-agents').action(async () => {
160
- const k = await withSpinner('Loading kit...', () => listKit());
161
- out(k.agents.map(slim), v => render.renderKitList(v, 'agent'));
162
- });
163
- kit.command('list-commands').action(async () => {
164
- const k = await withSpinner('Loading kit...', () => listKit());
165
- out(k.commands.map(slim), v => render.renderKitList(v, 'command'));
166
- });
167
- kit.command('list-skills').action(async () => {
168
- const k = await withSpinner('Loading kit...', () => listKit());
169
- out([...k.skills, ...k.skillsExtras].map(slim), v => render.renderKitList(v, 'skill'));
170
- });
166
+ kit.command('list-agents')
167
+ .option('--terse', 'Omit description; return only {kind, name} (PERF-15-01)')
168
+ .action(async (opts) => {
169
+ const k = await withSpinner('Loading kit...', () => listKit());
170
+ const variant = opts.terse ? slimTerse : slim;
171
+ out(k.agents.map(variant), v => render.renderKitList(v, 'agent'));
172
+ });
173
+ kit.command('list-commands')
174
+ .option('--terse', 'Omit description; return only {kind, name} (PERF-15-01)')
175
+ .action(async (opts) => {
176
+ const k = await withSpinner('Loading kit...', () => listKit());
177
+ const variant = opts.terse ? slimTerse : slim;
178
+ out(k.commands.map(variant), v => render.renderKitList(v, 'command'));
179
+ });
180
+ kit.command('list-skills')
181
+ .option('--terse', 'Omit description; return only {kind, name} (PERF-15-01)')
182
+ .action(async (opts) => {
183
+ const k = await withSpinner('Loading kit...', () => listKit());
184
+ const variant = opts.terse ? slimTerse : slim;
185
+ out([...k.skills, ...k.skillsExtras].map(variant), v => render.renderKitList(v, 'skill'));
186
+ });
171
187
  kit.command('get <kind> <name>').action(async (kind, name) => {
172
188
  const k = await listKit();
173
189
  const item = findItem(k, kind, name);
@@ -59,7 +59,11 @@ export async function verifyManifest(kitRoot) {
59
59
  missing.push(rel);
60
60
  continue;
61
61
  }
62
- const actual = crypto.createHash('sha256').update(buf).digest('hex');
62
+ // Normalize CRLF→LF before hashing so manifest is platform-stable.
63
+ // git checkout converts EOL on Windows but Linux CI checks out LF —
64
+ // hashing raw bytes would diverge across platforms.
65
+ const normalized = Buffer.from(buf.toString('binary').replace(/\r\n/g, '\n'), 'binary');
66
+ const actual = crypto.createHash('sha256').update(normalized).digest('hex');
63
67
  if (actual !== expected) {
64
68
  mismatches.push({ path: rel, expected: expected.slice(0, 16), actual: actual.slice(0, 16) });
65
69
  }
@@ -42,6 +42,7 @@ const TOOLS = [
42
42
  kind: { type: 'string', enum: ['agent', 'command', 'skill'], description: 'For action=get' },
43
43
  name: { type: 'string', description: 'For action=get' },
44
44
  query: { type: 'string', description: 'For action=search' },
45
+ terse: { type: 'boolean', description: 'For action=list-*: omit description, return only {kind, name}. Default false (PERF-15-01).' },
45
46
  },
46
47
  required: ['action'],
47
48
  },
@@ -152,10 +153,13 @@ export const PKG_VERSION = readPkgVersion();
152
153
 
153
154
  async function handleKit(args) {
154
155
  const kit = await listKit();
156
+ // PERF-15-01: terse mode skips description payload entirely. Backward-compat:
157
+ // args.terse undefined/false preserves slim()+summarize() cap-80 behavior.
158
+ const variant = args.terse === true ? slimTerse : slim;
155
159
  switch (args.action) {
156
- case 'list-agents': return kit.agents.map(slim);
157
- case 'list-commands': return kit.commands.map(slim);
158
- case 'list-skills': return [...kit.skills, ...kit.skillsExtras].map(slim);
160
+ case 'list-agents': return kit.agents.map(variant);
161
+ case 'list-commands': return kit.commands.map(variant);
162
+ case 'list-skills': return [...kit.skills, ...kit.skillsExtras].map(variant);
159
163
  case 'get': {
160
164
  const item = findItem(kit, args.kind, args.name);
161
165
  if (!item) return { error: `Not found: ${args.kind}/${args.name}` };
@@ -305,6 +309,13 @@ function slim(x) {
305
309
  return { kind: x.kind, name: x.name, description: summarize(x.description) };
306
310
  }
307
311
 
312
+ // PERF-15-01: terse variant — omits description entirely. Used when MCP client
313
+ // only needs name discovery (e.g. populating UI lists, validating slug references).
314
+ // Default action=list-* still returns description capped via slim()/summarize().
315
+ function slimTerse(x) {
316
+ return { kind: x.kind, name: x.name };
317
+ }
318
+
308
319
  // --- server bootstrap ---
309
320
 
310
321
  export async function createServer() {