@konductro/claude-plugin 2.4.0-rc.1 → 2.4.0-rc.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@konductro/claude-plugin",
3
- "version": "2.4.0-rc.1",
4
- "description": "Claude Code plugin for the Konductro platform — technical analysis and delivery tasks",
3
+ "version": "2.4.0-rc.2",
4
+ "description": "Claude Code plugin for the Konductro platform \u2014 technical analysis and delivery tasks",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "engines": {
@@ -11,6 +11,7 @@
11
11
  * KONDUCTRO_CLI_TOKEN — Personal CLI access token
12
12
  */
13
13
 
14
+ import { readFileSync } from 'node:fs';
14
15
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
15
16
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16
17
  import { z } from 'zod';
@@ -18,10 +19,29 @@ import { z } from 'zod';
18
19
  const KONDUCTRO_URL = process.env.KONDUCTRO_URL?.replace(/\/$/, '') || '';
19
20
  const CLI_TOKEN = process.env.KONDUCTRO_CLI_TOKEN || '';
20
21
 
22
+ /*
23
+ * What this plugin tells the server it is, on every request.
24
+ *
25
+ * READ FROM package.json, never a constant. The server's refusal of an outdated plugin is
26
+ * based on this string, so a hand-maintained copy that drifts from the published version
27
+ * is worse than no header at all: it would be believed.
28
+ *
29
+ * `readFileSync` rather than a JSON import assertion, whose syntax differs between Node 18
30
+ * and 20 and would break for whichever developers are on the other one.
31
+ *
32
+ * The shape is `<plugin>/<version>` and is identical across all four plugins, so the
33
+ * server parses one format rather than four.
34
+ */
35
+ const PLUGIN_VERSION = JSON.parse(
36
+ readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
37
+ ).version;
38
+ const PLUGIN_ID = `claude/${PLUGIN_VERSION}`;
39
+
21
40
  async function konductroFetch(path, options = {}) {
22
41
  const url = `${KONDUCTRO_URL}${path}`;
23
42
  const headers = {
24
43
  'Authorization': `Bearer ${CLI_TOKEN}`,
44
+ 'X-Konductro-Plugin': PLUGIN_ID,
25
45
  ...options.headers,
26
46
  };
27
47
  // Only set Content-Type and default body for methods that send JSON
@@ -300,6 +320,8 @@ server.tool(
300
320
  }
301
321
  }
302
322
 
323
+ contextText += renderDocumentTemplate(context.documentTemplate);
324
+
303
325
  return {
304
326
  content: [{
305
327
  type: 'text',
@@ -309,6 +331,51 @@ server.tool(
309
331
  }
310
332
  );
311
333
 
334
+ /**
335
+ * The document structure this workspace requires, as the agent must read it.
336
+ *
337
+ * APPENDED, never woven into the blob above. Four plugins share that server response and
338
+ * the agent's prompt is sensitive to its shape, so everything before this point is
339
+ * byte-identical to what it has always been. A workspace with no template gets an empty
340
+ * string here and therefore exactly today's context.
341
+ *
342
+ * THE WORDING IS IDENTICAL IN ALL FOUR PLUGINS, deliberately. The story this belongs to
343
+ * requires the same behaviour from Claude, Amazon Q, Codex and Cursor, and four separately
344
+ * worded prompts is precisely how that stops being true. Change it here and copy it, do
345
+ * not improve it in one place.
346
+ *
347
+ * Standing content is reproduced WORD FOR WORD rather than summarised. It is usually a
348
+ * compliance clause the workspace requires verbatim, which is the whole reason the field
349
+ * exists.
350
+ */
351
+ function renderDocumentTemplate(template) {
352
+ if (!template) return '';
353
+
354
+ let text = `### Required Document Structure\n\n`;
355
+ text += `This workspace requires technical analysis documents to follow **${template.name}** `;
356
+ text += `(v${template.version}). Produce these sections, in this order, using these exact headings.\n\n`;
357
+
358
+ for (const [index, section] of template.sections.entries()) {
359
+ text += `${index + 1}. **${section.title}**`;
360
+ if (section.intent) text += ` — ${section.intent}`;
361
+ if (section.mustCover) text += ` _(must cover: do not produce the document until you can answer this)_`;
362
+ text += `\n`;
363
+ if (section.diagram && section.diagram !== 'none') {
364
+ const kind = section.diagram === 'any' ? 'a Mermaid diagram of whichever type fits' : `a Mermaid ${section.diagram} diagram`;
365
+ text += ` Include ${kind} inside this section.\n`;
366
+ }
367
+ if (section.standingContent) {
368
+ text += ` Reproduce this text inside the section, word for word:\n`;
369
+ text += ` > ${section.standingContent.split('\n').join('\n > ')}\n`;
370
+ }
371
+ }
372
+
373
+ text += `\nThis structure replaces any default you would otherwise use. `;
374
+ text += `The sections marked "must cover" are what your exploration and your questions `;
375
+ text += `must be able to answer before you produce the document.\n\n`;
376
+ return text;
377
+ }
378
+
312
379
  // Tool: Submit tech analysis
313
380
  server.tool(
314
381
  'submit_tech_analysis',
@@ -28,7 +28,13 @@ Share a summary of the requirements with the user and confirm you're ready to be
28
28
 
29
29
  ### Step 3: Explore the Codebase
30
30
 
31
- Now analyse the local codebase. The user has the repository/repositories cloned in their current working directory. Use Glob, Grep, and Read to explore:
31
+ **If the context carried a "Required Document Structure", that is your brief.** Every section in it is something you must be able to answer by the end of this step, and the ones marked "must cover" are not optional. Explore with those sections in mind rather than working through the generic list below and hoping it covers them — a workspace that asks for a Regulatory Impact section is telling you what to go and find out, and nothing in the generic list will lead you there.
32
+
33
+ Where the structure asks for something the generic list does not cover, go and look for it. Where it omits something, you do not need to chase it.
34
+
35
+ If no structure was supplied, use the list below as-is.
36
+
37
+ The user has the repository/repositories cloned in their current working directory. Use Glob, Grep, and Read to explore:
32
38
 
33
39
  - **Project structure** — folder layout, module organisation
34
40
  - **Tech stack** — frameworks, versions, build tools (check package.json, pom.xml, build.gradle, etc.)
@@ -44,6 +50,10 @@ Discuss your findings with the user as you go. Ask clarifying questions about de
44
50
 
45
51
  ### Step 4: Impact Analysis
46
52
 
53
+ **Before moving on, check yourself against the required structure.** Take each section, and each "must cover" section especially, and ask whether you could write it now from what you have found. Where you could not, that is a question for the user or another pass over the codebase — ask it now rather than discovering the gap while writing the document, when the honest options are guessing or going back.
54
+
55
+ This is the step that makes the structure mean something. Producing the right headings over content that does not answer them is worse than the default document, because it looks like compliance.
56
+
47
57
  Based on the requirements and your codebase exploration, assess:
48
58
 
49
59
  - **What needs to change** — which files, modules, or services need modification
@@ -54,7 +64,13 @@ Based on the requirements and your codebase exploration, assess:
54
64
 
55
65
  ### Step 5: Produce the Document
56
66
 
57
- When the user is satisfied with the analysis, produce a structured technical analysis document. The document must include:
67
+ When the user is satisfied with the analysis, produce the document.
68
+
69
+ **If the context carried a "Required Document Structure", follow it exactly** — those sections, in that order, under those headings. It replaces the default list below rather than supplementing it: do not add the default sections alongside it, and do not reorder it to something you find more natural. Where a section carries standing content, reproduce that text word for word; it is usually a clause the workspace is required to publish, and paraphrasing it defeats the point of it being there. Where a section asks for a diagram, draw one, as Mermaid, inside that section.
70
+
71
+ A document produced here must be indistinguishable from one produced for the same workspace in Konductro itself. That is the whole purpose of the structure being sent.
72
+
73
+ **If no structure was supplied**, use this default list:
58
74
 
59
75
  1. **Codebase Overview** — what exists today (structure, stack, patterns)
60
76
  2. **Technical Stack** — frameworks, versions, build tools, deployment
@@ -83,4 +99,5 @@ After submission, confirm success and let the user know the document is availabl
83
99
  - Be thorough but focused — analyse what's relevant to the requirements
84
100
  - Ask the user questions — they know the codebase context you don't
85
101
  - Produce a complete, standalone document that an architect can use without additional context
102
+ - When a required document structure is supplied, it wins over anything in this file. It is the workspace's own standard, and your job is to meet it, not to improve on it
86
103
  - The conversation summary should capture the "why" behind decisions, not just the findings