superkit-mcp-server 1.2.5 → 1.2.7
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/ARCHITECTURE.md +52 -3
- package/SUPERKIT.md +32 -2
- package/build/index.js +293 -22
- package/build/tools/ProjectAssets.js +177 -0
- package/package.json +4 -1
- package/build/tools/__tests__/archTools.test.js +0 -42
- package/build/tools/__tests__/compoundTools.test.js +0 -60
- package/build/tools/__tests__/docsTools.test.js +0 -44
- package/build/tools/__tests__/gitTools.test.js +0 -45
- package/build/tools/__tests__/loggerTools.test.js +0 -74
- package/build/tools/__tests__/todoTools.test.js +0 -73
- package/build/tools/validators/__tests__/apiSchema.test.js +0 -77
- package/build/tools/validators/__tests__/convertRules.test.js +0 -38
- package/build/tools/validators/__tests__/frontendDesign.test.js +0 -55
- package/build/tools/validators/__tests__/geoChecker.test.js +0 -45
- package/build/tools/validators/__tests__/i18nChecker.test.js +0 -32
- package/build/tools/validators/__tests__/lintRunner.test.js +0 -65
- package/build/tools/validators/__tests__/mobileAudit.test.js +0 -40
- package/build/tools/validators/__tests__/playwrightRunner.test.js +0 -55
- package/build/tools/validators/__tests__/reactPerformanceChecker.test.js +0 -49
- package/build/tools/validators/__tests__/securityScan.test.js +0 -42
- package/build/tools/validators/__tests__/seoChecker.test.js +0 -44
- package/build/tools/validators/__tests__/testRunner.test.js +0 -49
- package/build/tools/validators/__tests__/typeCoverage.test.js +0 -62
package/ARCHITECTURE.md
CHANGED
|
@@ -17,17 +17,25 @@ Super-Kit is a model-agnostic and agent-agnostic toolkit designed to provide a h
|
|
|
17
17
|
## 🏗️ Directory Structure
|
|
18
18
|
|
|
19
19
|
```plaintext
|
|
20
|
-
super-kit/
|
|
20
|
+
super-kit/ # Global Super-Kit package (npm: superkit-mcp-server)
|
|
21
21
|
├── ARCHITECTURE.md # This file
|
|
22
22
|
├── SUPERKIT.md # Global rules and activation protocol
|
|
23
23
|
├── .core/ # Core engine-independent logic
|
|
24
24
|
│ ├── rules/ # Universal mandates (e.g., clean-code, security-first)
|
|
25
|
-
├── agents/ # The T-Shaped AI Team Personas
|
|
26
|
-
├── skills/ # The Knowledge Modules
|
|
25
|
+
├── agents/ # The T-Shaped AI Team Personas [source: "global"]
|
|
26
|
+
├── skills/ # The Knowledge Modules [source: "global"]
|
|
27
27
|
│ ├── meta/ # Session-resume, compound-docs, file-todos
|
|
28
28
|
│ ├── tech/ # Node.js, React, Python, Prisma
|
|
29
29
|
│ └── workflows/ # TDD, CI/CD, Code Review checklists
|
|
30
30
|
└── workflows/ # Slash commands and lifecycle loops
|
|
31
|
+
|
|
32
|
+
{your-project}/ # Any project using Super-Kit
|
|
33
|
+
└── .agents/ # Project-local assets [source: "project"]
|
|
34
|
+
├── agents/ # Custom agent .md files (e.g., my-domain-expert.md)
|
|
35
|
+
├── skills/
|
|
36
|
+
│ ├── tech/ # Tech skill dirs, each with a SKILL.md
|
|
37
|
+
│ └── meta/ # Meta skill dirs, each with a SKILL.md
|
|
38
|
+
└── workflows/ # Custom workflow .md files
|
|
31
39
|
```
|
|
32
40
|
|
|
33
41
|
---
|
|
@@ -100,3 +108,44 @@ The entry point is reading `SUPERKIT.md` to establish global rules.
|
|
|
100
108
|
- **Aider**: Run aider with the message `aider --message "Read SUPERKIT.md for your system instructions before doing anything else."`
|
|
101
109
|
|
|
102
110
|
Once the agent has loaded `SUPERKIT.md`, it will follow the instructions to activate the appropriate `@agent` which dynamically reads `SKILL.md` from the relevant directories.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 🗂️ Project-Based Assets
|
|
115
|
+
|
|
116
|
+
Super-Kit supports a two-scope asset system that allows any project to ship its own agents, skills, and workflows alongside the global Super-Kit package assets.
|
|
117
|
+
|
|
118
|
+
### Scope Definitions
|
|
119
|
+
|
|
120
|
+
| Scope | Source | Location | `source` Label |
|
|
121
|
+
|-------|--------|----------|----------------|
|
|
122
|
+
| **Global** | `superkit-mcp-server` npm package | `super-kit/agents/`, `super-kit/skills/` | `"global"` |
|
|
123
|
+
| **Project** | User's project `.agents/` folder | `{project-root}/.agents/` | `"project"` |
|
|
124
|
+
|
|
125
|
+
### Resolution Rules
|
|
126
|
+
|
|
127
|
+
- Project assets **complement** global assets — they never override or shadow them.
|
|
128
|
+
- If `.agents/` does not exist in a project, all project-scoped tools return empty results gracefully (no errors thrown).
|
|
129
|
+
- Asset names are validated to prevent path traversal — absolute paths and `..` components are rejected.
|
|
130
|
+
|
|
131
|
+
### MCP Tool Mapping
|
|
132
|
+
|
|
133
|
+
| Tool | Scope | Description |
|
|
134
|
+
|------|-------|-------------|
|
|
135
|
+
| `list_superkit_assets` | Global (default) | Lists global assets. Accepts `scope: "all"` to merge both scopes with source labels. |
|
|
136
|
+
| `load_superkit_agent` | Global | Loads an agent from the Super-Kit package. |
|
|
137
|
+
| `load_superkit_skill` | Global | Loads a skill from the Super-Kit package. |
|
|
138
|
+
| `load_superkit_workflow` | Global | Loads a workflow from the Super-Kit package. |
|
|
139
|
+
| `list_project_assets` | Project | Lists project-local assets from `.agents/`. Falls back to `process.cwd()` if no `projectPath` given. |
|
|
140
|
+
| `load_project_agent` | Project | Loads an agent from `{projectPath}/.agents/agents/`. |
|
|
141
|
+
| `load_project_skill` | Project | Loads a skill from `{projectPath}/.agents/skills/{category}/{skillName}/SKILL.md`. |
|
|
142
|
+
| `load_project_workflow` | Project | Loads a workflow from `{projectPath}/.agents/workflows/`. |
|
|
143
|
+
|
|
144
|
+
### Recommended Discovery Order
|
|
145
|
+
|
|
146
|
+
When an agent starts work on a project, it should:
|
|
147
|
+
|
|
148
|
+
1. Call `list_project_assets` to discover what the project provides.
|
|
149
|
+
2. Load project-specific agents/skills/workflows first (`load_project_*`).
|
|
150
|
+
3. Fall back to global Super-Kit assets (`load_superkit_*`) for anything not covered.
|
|
151
|
+
4. Use `list_superkit_assets({ scope: "all" })` for a unified merged view with source labels.
|
package/SUPERKIT.md
CHANGED
|
@@ -85,12 +85,18 @@ When user says: "Always use TypeScript strict mode"
|
|
|
85
85
|
|
|
86
86
|
## Available Tools
|
|
87
87
|
|
|
88
|
-
**Super-Kit MCP Tools:**
|
|
89
|
-
- `list_superkit_assets` - Lists all available agents, skills, and workflows.
|
|
88
|
+
**Super-Kit MCP Tools (Global Scope):**
|
|
89
|
+
- `list_superkit_assets` - Lists all available agents, skills, and workflows. Accepts optional `scope` (`"global"` | `"project"` | `"all"`) and `projectPath` params.
|
|
90
90
|
- `load_superkit_agent` - Loads Markdown instructions for an agent (e.g., `data-engineer`).
|
|
91
91
|
- `load_superkit_skill` - Loads Markdown instructions for a skill (e.g., `tech`, `api-patterns`).
|
|
92
92
|
- `load_superkit_workflow` - Loads a workflow guide (e.g., `work`, `explore`).
|
|
93
93
|
|
|
94
|
+
**Project-Scoped MCP Tools:**
|
|
95
|
+
- `list_project_assets` - Lists project-scoped agents, skills, and workflows from the `.agents/` folder.
|
|
96
|
+
- `load_project_agent` - Loads a project-scoped agent from `{projectPath}/.agents/agents/`.
|
|
97
|
+
- `load_project_skill` - Loads a project-scoped skill's `SKILL.md` from `{projectPath}/.agents/skills/`.
|
|
98
|
+
- `load_project_workflow` - Loads a project-scoped workflow from `{projectPath}/.agents/workflows/`.
|
|
99
|
+
|
|
94
100
|
**Core Development Tools:**
|
|
95
101
|
- `kit_create_checkpoint` - Create checkpoint before changes
|
|
96
102
|
- `kit_restore_checkpoint` - Restore checkpoint if needed
|
|
@@ -103,6 +109,30 @@ When user says: "Always use TypeScript strict mode"
|
|
|
103
109
|
- `kit_save_learning` - **Save lesson from user feedback**
|
|
104
110
|
- `kit_get_learnings` - Read saved learnings
|
|
105
111
|
|
|
112
|
+
## 🗂️ Project-Based Assets
|
|
113
|
+
|
|
114
|
+
Any project can define its own agents, skills, and workflows by creating a `.agents/` folder at the project root:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
{project-root}/
|
|
118
|
+
└── .agents/
|
|
119
|
+
├── agents/ # Custom agent .md files (e.g., my-domain-expert.md)
|
|
120
|
+
├── skills/
|
|
121
|
+
│ ├── tech/ # Tech skill dirs, each containing a SKILL.md
|
|
122
|
+
│ └── meta/ # Meta skill dirs, each containing a SKILL.md
|
|
123
|
+
└── workflows/ # Custom workflow .md files (e.g., deploy-staging.md)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Resolution rules:**
|
|
127
|
+
- Project assets have `"source": "project"` and **complement** (do not replace) global Super-Kit assets.
|
|
128
|
+
- Global Super-Kit assets always have `"source": "global"`.
|
|
129
|
+
- If `.agents/` does not exist, all project-scoped tools return empty results gracefully — no errors.
|
|
130
|
+
|
|
131
|
+
**When starting work on ANY project, ALWAYS:**
|
|
132
|
+
1. Call `list_project_assets` (or `list_superkit_assets` with `scope: "all"`) to discover project-specific agents, skills, and workflows.
|
|
133
|
+
2. Load project assets with `load_project_agent`, `load_project_skill`, or `load_project_workflow` before falling back to global equivalents.
|
|
134
|
+
3. Use global assets (`load_superkit_agent`, etc.) for anything not covered by the project's `.agents/` folder.
|
|
135
|
+
|
|
106
136
|
## Documentation Management
|
|
107
137
|
|
|
108
138
|
- Docs location: `./docs/`
|
package/build/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { compoundSearch, updateSolutionRef, validateCompound, auditStateDrift, s
|
|
|
16
16
|
import { bootstrapFolderDocs, checkDocsFreshness, discoverUndocumentedFolders, validateFolderDocs, } from "./tools/docsTools.js";
|
|
17
17
|
import { generateChangelog, validateChangelog, archiveCompleted, prePushHousekeeping, } from "./tools/gitTools.js";
|
|
18
18
|
import { validateSpecConsistency, completePlan, validateArchitecture, syncSpec, updateSpecPhase, } from "./tools/archTools.js";
|
|
19
|
+
import { list_project_agents, list_project_skills, list_project_workflows, load_project_agent_file, load_project_skill_file, load_project_workflow_file, } from "./tools/ProjectAssets.js";
|
|
19
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
21
|
const __dirname = path.dirname(__filename);
|
|
21
22
|
const superKitRoot = path.resolve(__dirname, "../");
|
|
@@ -119,7 +120,23 @@ const TOOLS = [
|
|
|
119
120
|
},
|
|
120
121
|
{
|
|
121
122
|
name: "call_tool_todo_manager",
|
|
122
|
-
description:
|
|
123
|
+
description: `Manages todos. Per-action usage:
|
|
124
|
+
|
|
125
|
+
• nextId — Returns the next available todo ID. No extra params needed.
|
|
126
|
+
|
|
127
|
+
• create — Creates a new todo file. Required: title (string), description (1-2 sentence problem statement), priority ("p0"|"p1"|"p2"|"p3"), criteria (string array of acceptance criteria). Optional: projectPath.
|
|
128
|
+
Example: { action: "create", title: "Add auth", description: "Implement JWT login.", priority: "p2", criteria: ["User can log in", "Token is stored"], projectPath: "." }
|
|
129
|
+
|
|
130
|
+
• start — Marks a todo as in-progress. Required: todoId = RELATIVE PATH to the todo file, e.g. "todos/001-pending-p2-my-task.md". The file must exist at that path relative to projectPath.
|
|
131
|
+
Example: { action: "start", todoId: "todos/001-pending-p2-my-task.md", projectPath: "." }
|
|
132
|
+
|
|
133
|
+
• done — Marks a todo as done. Required: todoId = relative path (same format as start). All acceptance criteria checkboxes must be checked, or pass force: true to bypass.
|
|
134
|
+
Example: { action: "done", todoId: "todos/001-in-progress-p2-my-task.md", force: true, projectPath: "." }
|
|
135
|
+
|
|
136
|
+
• complete — Marks a todo as complete (final state). Required: todoId = relative path (same format as start/done).
|
|
137
|
+
Example: { action: "complete", todoId: "todos/001-done-p2-my-task.md", force: true, projectPath: "." }
|
|
138
|
+
|
|
139
|
+
⚠️ IMPORTANT: todoId must be the FULL RELATIVE FILE PATH (e.g. "todos/001-in-progress-p2-my-task.md"), NOT just the numeric ID ("001"). The filename changes with each status transition, so always use the current filename on disk.`,
|
|
123
140
|
inputSchema: {
|
|
124
141
|
type: "object",
|
|
125
142
|
properties: {
|
|
@@ -127,12 +144,33 @@ const TOOLS = [
|
|
|
127
144
|
type: "string",
|
|
128
145
|
enum: ["nextId", "create", "start", "done", "complete"],
|
|
129
146
|
},
|
|
130
|
-
title: {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
title: {
|
|
148
|
+
type: "string",
|
|
149
|
+
description: "Todo title. Used by: create.",
|
|
150
|
+
},
|
|
151
|
+
description: {
|
|
152
|
+
type: "string",
|
|
153
|
+
description: "1-2 sentence problem statement. Used by: create.",
|
|
154
|
+
},
|
|
155
|
+
priority: {
|
|
156
|
+
type: "string",
|
|
157
|
+
enum: ["p0", "p1", "p2", "p3"],
|
|
158
|
+
description: "Priority level. p0=critical, p1=urgent, p2=normal, p3=low. Used by: create.",
|
|
159
|
+
},
|
|
160
|
+
criteria: {
|
|
161
|
+
type: "array",
|
|
162
|
+
items: { type: "string" },
|
|
163
|
+
description: "Acceptance criteria checklist items. Used by: create.",
|
|
164
|
+
},
|
|
165
|
+
todoId: {
|
|
166
|
+
type: "string",
|
|
167
|
+
description: "RELATIVE PATH to the todo file from projectPath, e.g. 'todos/001-pending-p2-my-task.md'. NOT just the numeric ID. Used by: start, done, complete.",
|
|
168
|
+
},
|
|
169
|
+
force: {
|
|
170
|
+
type: "boolean",
|
|
171
|
+
default: false,
|
|
172
|
+
description: "Bypass terminal-state or unchecked-criteria guards. Used by: start, done, complete.",
|
|
173
|
+
},
|
|
136
174
|
projectPath: { type: "string", default: "." },
|
|
137
175
|
},
|
|
138
176
|
required: ["action", "projectPath"],
|
|
@@ -233,10 +271,93 @@ const TOOLS = [
|
|
|
233
271
|
description: "Lists all available agents, skills, and workflows in the Super-Kit repository.",
|
|
234
272
|
inputSchema: {
|
|
235
273
|
type: "object",
|
|
236
|
-
properties: {
|
|
274
|
+
properties: {
|
|
275
|
+
scope: {
|
|
276
|
+
type: "string",
|
|
277
|
+
enum: ["global", "project", "all"],
|
|
278
|
+
default: "global",
|
|
279
|
+
description: "Which scope to list: 'global' (superkit package assets), 'project' (.agents/ folder assets), or 'all' (merged with source labels on every entry).",
|
|
280
|
+
},
|
|
281
|
+
projectPath: {
|
|
282
|
+
type: "string",
|
|
283
|
+
description: "Project root path used when scope includes 'project'. Defaults to process.cwd().",
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
required: [],
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: "list_project_assets",
|
|
291
|
+
description: "Lists project-scoped agents, skills, and workflows from the .agents/ folder in the given project directory. Falls back to process.cwd() if no projectPath is given.",
|
|
292
|
+
inputSchema: {
|
|
293
|
+
type: "object",
|
|
294
|
+
properties: {
|
|
295
|
+
projectPath: {
|
|
296
|
+
type: "string",
|
|
297
|
+
description: "Absolute path to the project root. Defaults to process.cwd().",
|
|
298
|
+
},
|
|
299
|
+
},
|
|
237
300
|
required: [],
|
|
238
301
|
},
|
|
239
302
|
},
|
|
303
|
+
{
|
|
304
|
+
name: "load_project_agent",
|
|
305
|
+
description: "Loads a project-scoped agent markdown file from {projectPath}/.agents/agents/{agentName}.md",
|
|
306
|
+
inputSchema: {
|
|
307
|
+
type: "object",
|
|
308
|
+
properties: {
|
|
309
|
+
agentName: {
|
|
310
|
+
type: "string",
|
|
311
|
+
description: "Agent name without .md extension.",
|
|
312
|
+
},
|
|
313
|
+
projectPath: {
|
|
314
|
+
type: "string",
|
|
315
|
+
description: "Absolute path to the project root. Defaults to process.cwd().",
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
required: ["agentName"],
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: "load_project_skill",
|
|
323
|
+
description: "Loads a project-scoped skill's SKILL.md from {projectPath}/.agents/skills/{category}/{skillName}/SKILL.md",
|
|
324
|
+
inputSchema: {
|
|
325
|
+
type: "object",
|
|
326
|
+
properties: {
|
|
327
|
+
category: {
|
|
328
|
+
type: "string",
|
|
329
|
+
description: "Skill category: 'tech' or 'meta'.",
|
|
330
|
+
},
|
|
331
|
+
skillName: {
|
|
332
|
+
type: "string",
|
|
333
|
+
description: "Skill directory name.",
|
|
334
|
+
},
|
|
335
|
+
projectPath: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Absolute path to the project root. Defaults to process.cwd().",
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
required: ["category", "skillName"],
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: "load_project_workflow",
|
|
345
|
+
description: "Loads a project-scoped workflow markdown file from {projectPath}/.agents/workflows/{workflowName}.md",
|
|
346
|
+
inputSchema: {
|
|
347
|
+
type: "object",
|
|
348
|
+
properties: {
|
|
349
|
+
workflowName: {
|
|
350
|
+
type: "string",
|
|
351
|
+
description: "Workflow name without .md extension.",
|
|
352
|
+
},
|
|
353
|
+
projectPath: {
|
|
354
|
+
type: "string",
|
|
355
|
+
description: "Absolute path to the project root. Defaults to process.cwd().",
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
required: ["workflowName"],
|
|
359
|
+
},
|
|
360
|
+
},
|
|
240
361
|
{
|
|
241
362
|
name: "load_superkit_agent",
|
|
242
363
|
description: "Loads the instruction markdown for a specific specialist agent.",
|
|
@@ -302,6 +423,13 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
|
302
423
|
prompts.push({
|
|
303
424
|
name: file.replace(".toml", ""),
|
|
304
425
|
description: description,
|
|
426
|
+
arguments: [
|
|
427
|
+
{
|
|
428
|
+
name: "args",
|
|
429
|
+
description: "Arguments to pass to the command",
|
|
430
|
+
required: false,
|
|
431
|
+
},
|
|
432
|
+
],
|
|
305
433
|
});
|
|
306
434
|
}
|
|
307
435
|
catch (e) {
|
|
@@ -316,8 +444,18 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
|
316
444
|
return { prompts: [] };
|
|
317
445
|
}
|
|
318
446
|
});
|
|
447
|
+
export function apply_prompt_args(promptText, userArgs) {
|
|
448
|
+
// Substitute {{#if args}} ... {{else}} ... {{/if}} Handlebars blocks
|
|
449
|
+
promptText = promptText.replace(/\{\{#if args\}\}([\s\S]*?)\{\{else\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, ifBlock, elseBlock) => userArgs.trim() ? ifBlock : elseBlock);
|
|
450
|
+
// Substitute {{#if args}} ... {{/if}} blocks (no else branch)
|
|
451
|
+
promptText = promptText.replace(/\{\{#if args\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, ifBlock) => (userArgs.trim() ? ifBlock : ""));
|
|
452
|
+
// Substitute all {{args}} occurrences with the actual user-provided args
|
|
453
|
+
promptText = promptText.replace(/\{\{args\}\}/g, userArgs);
|
|
454
|
+
return promptText;
|
|
455
|
+
}
|
|
319
456
|
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
320
457
|
const promptName = request.params.name;
|
|
458
|
+
const userArgs = request.params.arguments?.args ?? "";
|
|
321
459
|
const commandFile = `${promptName}.toml`;
|
|
322
460
|
const basePath = path.join(superKitRoot, "commands");
|
|
323
461
|
const safePath = getSafePath(basePath, commandFile);
|
|
@@ -328,6 +466,7 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
|
328
466
|
const content = await fs.readFile(safePath, "utf-8");
|
|
329
467
|
const parsed = toml.parse(content);
|
|
330
468
|
let promptText = parsed?.prompt || `Execute the ${promptName} command.`;
|
|
469
|
+
promptText = apply_prompt_args(promptText, userArgs);
|
|
331
470
|
// Resolve @{path} includes from super-kit package root
|
|
332
471
|
const includePattern = /@\{([^}]+)\}/g;
|
|
333
472
|
let match;
|
|
@@ -475,29 +614,106 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
475
614
|
return { content: [{ type: "text", text: res }] };
|
|
476
615
|
}
|
|
477
616
|
if (request.params.name === "list_superkit_assets") {
|
|
617
|
+
const args = request.params.arguments;
|
|
618
|
+
const scope = args?.scope ?? "global";
|
|
619
|
+
const projectPath = args?.projectPath;
|
|
478
620
|
const agentsPath = path.join(superKitRoot, "agents");
|
|
479
621
|
const skillsTechPath = path.join(superKitRoot, "skills", "tech");
|
|
480
622
|
const skillsMetaPath = path.join(superKitRoot, "skills", "meta");
|
|
481
623
|
const workflowsPath = path.join(superKitRoot, "skills", "workflows");
|
|
482
624
|
const commandsPath = path.join(superKitRoot, "commands");
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
625
|
+
// Build global asset lists (used for scope "global" or "all")
|
|
626
|
+
let globalData = null;
|
|
627
|
+
if (scope !== "project") {
|
|
628
|
+
const agents = await listDirectorySafe(agentsPath);
|
|
629
|
+
const techSkills = await listDirectorySafe(skillsTechPath);
|
|
630
|
+
const metaSkills = await listDirectorySafe(skillsMetaPath);
|
|
631
|
+
const workflows = await listDirectorySafe(workflowsPath);
|
|
632
|
+
const commands = await listDirectorySafe(commandsPath);
|
|
633
|
+
if (scope === "global") {
|
|
634
|
+
// Original backward-compatible format — no source labels
|
|
635
|
+
globalData = {
|
|
636
|
+
agents: agents.map((a) => a.replace(".md", "")),
|
|
637
|
+
skills: {
|
|
638
|
+
tech: techSkills.map((s) => s.replace("/", "")),
|
|
639
|
+
meta: metaSkills.map((s) => s.replace("/", "")),
|
|
640
|
+
},
|
|
641
|
+
workflows: workflows.map((w) => w.replace(".md", "")),
|
|
642
|
+
commands: commands.map((c) => c.replace(".toml", "")),
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
// "all" scope — include source labels on every entry
|
|
647
|
+
globalData = {
|
|
648
|
+
agents: agents.map((a) => ({
|
|
649
|
+
name: a.replace(".md", ""),
|
|
650
|
+
source: "global",
|
|
651
|
+
})),
|
|
652
|
+
skills: {
|
|
653
|
+
tech: techSkills.map((s) => ({
|
|
654
|
+
name: s.replace("/", ""),
|
|
655
|
+
source: "global",
|
|
656
|
+
})),
|
|
657
|
+
meta: metaSkills.map((s) => ({
|
|
658
|
+
name: s.replace("/", ""),
|
|
659
|
+
source: "global",
|
|
660
|
+
})),
|
|
661
|
+
},
|
|
662
|
+
workflows: workflows.map((w) => ({
|
|
663
|
+
name: w.replace(".md", ""),
|
|
664
|
+
source: "global",
|
|
665
|
+
})),
|
|
666
|
+
commands: commands.map((c) => ({
|
|
667
|
+
name: c.replace(".toml", ""),
|
|
668
|
+
source: "global",
|
|
669
|
+
})),
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
// Build project asset lists (used for scope "project" or "all")
|
|
674
|
+
let projectData = null;
|
|
675
|
+
if (scope !== "global") {
|
|
676
|
+
const [projAgents, projSkills, projWorkflows] = await Promise.all([
|
|
677
|
+
list_project_agents(projectPath),
|
|
678
|
+
list_project_skills(projectPath),
|
|
679
|
+
list_project_workflows(projectPath),
|
|
680
|
+
]);
|
|
681
|
+
projectData = {
|
|
682
|
+
agents: projAgents.map((a) => ({ name: a, source: "project" })),
|
|
683
|
+
skills: {
|
|
684
|
+
tech: projSkills.tech.map((s) => ({ name: s, source: "project" })),
|
|
685
|
+
meta: projSkills.meta.map((s) => ({ name: s, source: "project" })),
|
|
686
|
+
},
|
|
687
|
+
workflows: projWorkflows.map((w) => ({ name: w, source: "project" })),
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
// Compose the final response payload
|
|
691
|
+
let payload;
|
|
692
|
+
if (scope === "global") {
|
|
693
|
+
payload = globalData;
|
|
694
|
+
}
|
|
695
|
+
else if (scope === "project") {
|
|
696
|
+
payload = projectData;
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
// "all" — deep-merge both lists
|
|
700
|
+
const g = globalData;
|
|
701
|
+
const p = projectData;
|
|
702
|
+
payload = {
|
|
703
|
+
agents: [...g.agents, ...p.agents],
|
|
704
|
+
skills: {
|
|
705
|
+
tech: [...g.skills.tech, ...p.skills.tech],
|
|
706
|
+
meta: [...g.skills.meta, ...p.skills.meta],
|
|
707
|
+
},
|
|
708
|
+
workflows: [...g.workflows, ...p.workflows],
|
|
709
|
+
commands: g.commands,
|
|
710
|
+
};
|
|
711
|
+
}
|
|
488
712
|
return {
|
|
489
713
|
content: [
|
|
490
714
|
{
|
|
491
715
|
type: "text",
|
|
492
|
-
text: JSON.stringify(
|
|
493
|
-
agents: agents.map((a) => a.replace(".md", "")),
|
|
494
|
-
skills: {
|
|
495
|
-
tech: techSkills.map((s) => s.replace("/", "")),
|
|
496
|
-
meta: metaSkills.map((s) => s.replace("/", "")),
|
|
497
|
-
},
|
|
498
|
-
workflows: workflows.map((w) => w.replace(".md", "")),
|
|
499
|
-
commands: commands.map((c) => c.replace(".toml", "")),
|
|
500
|
-
}, null, 2),
|
|
716
|
+
text: JSON.stringify(payload, null, 2),
|
|
501
717
|
},
|
|
502
718
|
],
|
|
503
719
|
};
|
|
@@ -555,6 +771,61 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
555
771
|
const content = await fs.readFile(safePath, "utf-8");
|
|
556
772
|
return { content: [{ type: "text", text: content }] };
|
|
557
773
|
}
|
|
774
|
+
if (request.params.name === "list_project_assets") {
|
|
775
|
+
const args = request.params.arguments;
|
|
776
|
+
const projectPath = args?.projectPath;
|
|
777
|
+
const [agents, skills, workflows] = await Promise.all([
|
|
778
|
+
list_project_agents(projectPath),
|
|
779
|
+
list_project_skills(projectPath),
|
|
780
|
+
list_project_workflows(projectPath),
|
|
781
|
+
]);
|
|
782
|
+
return {
|
|
783
|
+
content: [
|
|
784
|
+
{
|
|
785
|
+
type: "text",
|
|
786
|
+
text: JSON.stringify({
|
|
787
|
+
source: "project",
|
|
788
|
+
agents: agents.map((a) => ({ name: a, source: "project" })),
|
|
789
|
+
skills: {
|
|
790
|
+
tech: skills.tech.map((s) => ({
|
|
791
|
+
name: s,
|
|
792
|
+
source: "project",
|
|
793
|
+
})),
|
|
794
|
+
meta: skills.meta.map((s) => ({
|
|
795
|
+
name: s,
|
|
796
|
+
source: "project",
|
|
797
|
+
})),
|
|
798
|
+
},
|
|
799
|
+
workflows: workflows.map((w) => ({
|
|
800
|
+
name: w,
|
|
801
|
+
source: "project",
|
|
802
|
+
})),
|
|
803
|
+
}, null, 2),
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
if (request.params.name === "load_project_agent") {
|
|
809
|
+
const args = request.params.arguments;
|
|
810
|
+
if (!args.agentName)
|
|
811
|
+
throw new Error("Missing agentName");
|
|
812
|
+
const content = await load_project_agent_file(args.agentName, args.projectPath);
|
|
813
|
+
return { content: [{ type: "text", text: content }] };
|
|
814
|
+
}
|
|
815
|
+
if (request.params.name === "load_project_skill") {
|
|
816
|
+
const args = request.params.arguments;
|
|
817
|
+
if (!args.category || !args.skillName)
|
|
818
|
+
throw new Error("Missing category or skillName");
|
|
819
|
+
const content = await load_project_skill_file(args.category, args.skillName, args.projectPath);
|
|
820
|
+
return { content: [{ type: "text", text: content }] };
|
|
821
|
+
}
|
|
822
|
+
if (request.params.name === "load_project_workflow") {
|
|
823
|
+
const args = request.params.arguments;
|
|
824
|
+
if (!args.workflowName)
|
|
825
|
+
throw new Error("Missing workflowName");
|
|
826
|
+
const content = await load_project_workflow_file(args.workflowName, args.projectPath);
|
|
827
|
+
return { content: [{ type: "text", text: content }] };
|
|
828
|
+
}
|
|
558
829
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
559
830
|
}
|
|
560
831
|
catch (error) {
|