@konductro/claude-plugin 2.0.0 → 2.1.1
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/README.md +3 -0
- package/package.json +1 -1
- package/servers/konductro-api.js +82 -1
- package/skills/bug-enrich/SKILL.md +70 -0
- package/skills/decompose/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -35,6 +35,7 @@ Skills are guided, multi-step workflows invoked with a slash command:
|
|
|
35
35
|
| `/find-prototype` | Find and download the approved UX prototype for the current project |
|
|
36
36
|
| `/profile-repository` | Scan the current repo and submit its profile to Konductro |
|
|
37
37
|
| `/start-ticket` | Pick up an assigned ticket — creates branch, pushes ticket spec, sets status |
|
|
38
|
+
| `/bug-enrich` | Enrich a bug ticket with technical analysis — explores codebase and submits structured context |
|
|
38
39
|
|
|
39
40
|
## Tools
|
|
40
41
|
|
|
@@ -82,6 +83,8 @@ Tools are called automatically by Claude based on natural language. You don't in
|
|
|
82
83
|
| Tool | What it does |
|
|
83
84
|
|---|---|
|
|
84
85
|
| `profile_repository` | Submit a repository profile (tech stack, APIs, dependencies) |
|
|
86
|
+
| `get_bug_for_enrichment` | Load a bug ticket and project context for enrichment |
|
|
87
|
+
| `submit_bug_enrichment` | Submit structured technical enrichment for a bug ticket |
|
|
85
88
|
|
|
86
89
|
### Examples
|
|
87
90
|
|
package/package.json
CHANGED
package/servers/konductro-api.js
CHANGED
|
@@ -297,7 +297,7 @@ server.tool(
|
|
|
297
297
|
title: z.string().describe('Task title'),
|
|
298
298
|
description: z.string().describe('Technical description of the task'),
|
|
299
299
|
repositoryId: z.string().describe('Repository ID from the context'),
|
|
300
|
-
type: z.
|
|
300
|
+
type: z.string().trim().max(24).optional().describe('Short free-text tech tag derived from the repo stack (e.g. C#, PHP, Node, Java, UI, Infra); one token, max 24 chars, no fixed list'),
|
|
301
301
|
acceptanceCriteria: z.array(z.string()).default([]).describe('Technical acceptance criteria'),
|
|
302
302
|
architecturalNotes: z.array(z.string()).default([]).describe('Implementation notes for the agent'),
|
|
303
303
|
componentPath: z.string().optional().nullable().describe('Primary file/directory path for this task'),
|
|
@@ -882,6 +882,87 @@ server.tool(
|
|
|
882
882
|
}
|
|
883
883
|
);
|
|
884
884
|
|
|
885
|
+
// Tool: Get bug context for enrichment
|
|
886
|
+
server.tool(
|
|
887
|
+
'get_bug_for_enrichment',
|
|
888
|
+
'Load a bug ticket and its project context for enrichment. Returns the bug description, acceptance criteria, project name, and existing notes.',
|
|
889
|
+
{
|
|
890
|
+
ticketId: z.string().describe('The ticket ID or key (e.g. KON-42) of the bug to enrich'),
|
|
891
|
+
},
|
|
892
|
+
async ({ ticketId }) => {
|
|
893
|
+
try {
|
|
894
|
+
const ctx = await konductroFetch(`/api/cli/bugs/${encodeURIComponent(ticketId)}/context`);
|
|
895
|
+
|
|
896
|
+
let text = `## Bug Context\n\n`;
|
|
897
|
+
text += `**Ticket:** ${ctx.key} — ${ctx.title}\n`;
|
|
898
|
+
text += `**Project:** ${ctx.projectName ?? 'Unknown'}\n`;
|
|
899
|
+
text += `**Phase:** ${ctx.phaseName ?? 'Unknown'}\n`;
|
|
900
|
+
if (ctx.componentPath) text += `**Component:** ${ctx.componentPath}\n`;
|
|
901
|
+
if (ctx.repository) text += `**Repository:** ${ctx.repository.name} (${ctx.repository.repoType}) — ${ctx.repository.repoUrl}\n`;
|
|
902
|
+
text += `\n`;
|
|
903
|
+
|
|
904
|
+
text += `### Description\n\n${ctx.description}\n\n`;
|
|
905
|
+
|
|
906
|
+
if (ctx.acceptanceCriteria?.length > 0) {
|
|
907
|
+
text += `### Acceptance Criteria\n\n`;
|
|
908
|
+
ctx.acceptanceCriteria.forEach((ac, i) => { text += `${i + 1}. ${ac}\n`; });
|
|
909
|
+
text += `\n`;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (ctx.architecturalNotes?.length > 0) {
|
|
913
|
+
text += `### Existing Notes\n\n`;
|
|
914
|
+
ctx.architecturalNotes.forEach(n => { text += `- ${n}\n`; });
|
|
915
|
+
text += `\n`;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
return { content: [{ type: 'text', text }] };
|
|
919
|
+
} catch (err) {
|
|
920
|
+
const msg = err.message?.includes('BUG_NOT_FOUND') || err.message?.includes('404')
|
|
921
|
+
? `Ticket ${ticketId} not found or is not a bug.`
|
|
922
|
+
: `Failed to load bug context: ${err.message}`;
|
|
923
|
+
return { content: [{ type: 'text', text: msg }], isError: true };
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
// Tool: Submit bug enrichment
|
|
929
|
+
server.tool(
|
|
930
|
+
'submit_bug_enrichment',
|
|
931
|
+
'Submit structured technical enrichment for a bug ticket. At least one field must be provided. The enrichment is append-only — the original description is never modified.',
|
|
932
|
+
{
|
|
933
|
+
ticketId: z.string().describe('The ticket ID or key (e.g. KON-42) of the bug to enrich'),
|
|
934
|
+
suspectedRootCause: z.string().optional().describe('Your assessment of why the bug occurs'),
|
|
935
|
+
affectedComponents: z.array(z.string()).optional().describe('File paths or module names involved'),
|
|
936
|
+
stackTraceHints: z.array(z.string()).optional().describe('Relevant error origins, log lines, or exception paths'),
|
|
937
|
+
investigationSteps: z.array(z.string()).optional().describe('What you checked and what you found'),
|
|
938
|
+
verifyFixCriteria: z.array(z.string()).optional().describe('Conditions that confirm the bug is fixed (appended to acceptance criteria)'),
|
|
939
|
+
},
|
|
940
|
+
async ({ ticketId, suspectedRootCause, affectedComponents, stackTraceHints, investigationSteps, verifyFixCriteria }) => {
|
|
941
|
+
if (!suspectedRootCause && !affectedComponents?.length && !stackTraceHints?.length && !investigationSteps?.length && !verifyFixCriteria?.length) {
|
|
942
|
+
return { content: [{ type: 'text', text: 'At least one enrichment field must be provided.' }], isError: true };
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
try {
|
|
946
|
+
const result = await konductroFetch(`/api/cli/bugs/${encodeURIComponent(ticketId)}/enrich`, {
|
|
947
|
+
method: 'POST',
|
|
948
|
+
body: JSON.stringify({ suspectedRootCause, affectedComponents, stackTraceHints, investigationSteps, verifyFixCriteria }),
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
const applied = result.fieldsApplied?.length > 0
|
|
952
|
+
? `Enrichment applied: ${result.fieldsApplied.join(', ')}`
|
|
953
|
+
: 'No new enrichment applied (fields may already exist on the ticket).';
|
|
954
|
+
return { content: [{ type: 'text', text: applied }] };
|
|
955
|
+
} catch (err) {
|
|
956
|
+
const msg = err.message?.includes('BUG_NOT_FOUND') || err.message?.includes('404')
|
|
957
|
+
? `Ticket ${ticketId} not found or is not a bug.`
|
|
958
|
+
: err.message?.includes('INVALID_ENRICHMENT')
|
|
959
|
+
? 'At least one enrichment field must be provided.'
|
|
960
|
+
: `Failed to submit enrichment: ${err.message}`;
|
|
961
|
+
return { content: [{ type: 'text', text: msg }], isError: true };
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
);
|
|
965
|
+
|
|
885
966
|
// Start the server
|
|
886
967
|
async function main() {
|
|
887
968
|
const transport = new StdioServerTransport();
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bug-enrich
|
|
3
|
+
description: Enrich an existing bug ticket with technical analysis. Use when assigned to triage a bug — fetches the ticket, explores the codebase locally, and submits structured technical context back to Konductro.
|
|
4
|
+
allowed-tools: Read, Grep, Glob, Bash, mcp__konductro__get_bug_for_enrichment, mcp__konductro__submit_bug_enrichment
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Konductro Bug Enrichment
|
|
8
|
+
|
|
9
|
+
You are enriching an existing bug ticket with technical context for the Konductro delivery platform. Your role is to add structured technical detail — never to rewrite or modify the user's original bug description.
|
|
10
|
+
|
|
11
|
+
## Critical Constraint
|
|
12
|
+
|
|
13
|
+
**DO NOT modify the original `description` of the ticket.** The enrichment is append-only. Your job is to add technical context (root cause, affected components, investigation steps) — the user's original report is preserved byte-for-byte by the server.
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
### Step 1: Accept Ticket ID
|
|
18
|
+
|
|
19
|
+
The user provides a ticket ID (e.g. `KON-42` or a UUID) as a positional argument from `/bug-enrich <ticket-id>`.
|
|
20
|
+
|
|
21
|
+
### Step 2: Load Bug Context
|
|
22
|
+
|
|
23
|
+
Call `get_bug_for_enrichment` with the ticket ID. This returns:
|
|
24
|
+
- The bug title, description, and existing acceptance criteria
|
|
25
|
+
- Project and phase context
|
|
26
|
+
- Any existing architectural notes or component path
|
|
27
|
+
|
|
28
|
+
Review the bug report and share a summary with the user. Confirm you understand the issue.
|
|
29
|
+
|
|
30
|
+
### Step 3: Explore the Codebase
|
|
31
|
+
|
|
32
|
+
The user has the target repository cloned locally. Use Glob, Grep, and Read to investigate:
|
|
33
|
+
|
|
34
|
+
- **Affected code paths** — trace the flow described in the bug report
|
|
35
|
+
- **Potential root cause** — look for the code that could produce the described behaviour
|
|
36
|
+
- **Related components** — what files/modules are involved
|
|
37
|
+
- **Stack trace clues** — if error messages are mentioned, find where they originate
|
|
38
|
+
- **Fix verification** — what would need to be true for the bug to be resolved
|
|
39
|
+
|
|
40
|
+
Focus your exploration on what's relevant to the bug. Don't scan the entire codebase.
|
|
41
|
+
|
|
42
|
+
### Step 4: Plan the Enrichment
|
|
43
|
+
|
|
44
|
+
Based on your investigation, prepare structured enrichment fields:
|
|
45
|
+
|
|
46
|
+
- **suspectedRootCause** — your best assessment of why the bug occurs (reference specific code)
|
|
47
|
+
- **affectedComponents** — file paths or module names involved
|
|
48
|
+
- **stackTraceHints** — relevant error origins, log lines, or exception paths
|
|
49
|
+
- **investigationSteps** — what you checked and what you found
|
|
50
|
+
- **verifyFixCriteria** — specific conditions that confirm the bug is fixed (these get appended to acceptance criteria)
|
|
51
|
+
|
|
52
|
+
Present your findings to the user before submitting.
|
|
53
|
+
|
|
54
|
+
### Step 5: Submit Enrichment
|
|
55
|
+
|
|
56
|
+
After the user approves, call `submit_bug_enrichment` with the ticket ID and your structured findings. The server applies them using append-only rules:
|
|
57
|
+
- `architecturalNotes` receives prefixed entries
|
|
58
|
+
- `componentPath` is set only if currently empty
|
|
59
|
+
- `acceptanceCriteria` receives verify-fix criteria (de-duplicated)
|
|
60
|
+
|
|
61
|
+
Report success and summarise what was applied.
|
|
62
|
+
|
|
63
|
+
## Important Rules
|
|
64
|
+
|
|
65
|
+
- Always load the bug context first — don't assume or hallucinate ticket contents
|
|
66
|
+
- Explore the ACTUAL local codebase — don't invent file paths or code snippets
|
|
67
|
+
- Reference specific files, line numbers, and function names in your findings
|
|
68
|
+
- Present findings for user review before submitting
|
|
69
|
+
- Never modify the original description — enrichment is additive only
|
|
70
|
+
- If you can't find relevant code, say so honestly rather than guessing
|
|
@@ -45,7 +45,7 @@ Based on the story requirements and your codebase understanding, plan the tasks.
|
|
|
45
45
|
- **Execution order** — what needs to be built first (e.g., schema before API before UI)
|
|
46
46
|
- **Task boundaries** — each task should be a single PR, touching one concern
|
|
47
47
|
- **Repository assignment** — which repo does each task belong to
|
|
48
|
-
- **Task type** — `
|
|
48
|
+
- **Task type** — a short free-text tech tag derived from the target repo's stack (e.g. `C#`, `PHP`, `Node`, `Java`, `Angular`, `UI`, `Infra`). One canonical token, max 24 chars — there is no fixed list; match the repo's actual language/domain.
|
|
49
49
|
- **Dependencies between tasks** — task 2 may depend on task 1's API
|
|
50
50
|
|
|
51
51
|
Present your proposed decomposition to the user before submitting.
|
|
@@ -57,7 +57,7 @@ For each task, produce the full developer brief — this is the complete impleme
|
|
|
57
57
|
1. **title** — short, action-oriented (e.g., "Add sprint.projectId column and migration")
|
|
58
58
|
2. **description** — technical description of what to build and how, referencing specific files, patterns, and APIs
|
|
59
59
|
3. **repositoryId** — from the context (the repo this task targets)
|
|
60
|
-
4. **type** — `
|
|
60
|
+
4. **type** — short free-text tech tag from the repo's stack (e.g. `C#`, `PHP`, `Node`, `Java`, `Angular`, `UI`, `Infra`); one canonical token, max 24 chars, no fixed list
|
|
61
61
|
5. **acceptanceCriteria** — specific, testable criteria for this task
|
|
62
62
|
6. **architecturalNotes** — implementation hints, patterns to follow, gotchas
|
|
63
63
|
7. **componentPath** — primary file or directory being changed
|