@neobiotechlabs/neobiotech-dev-agent 0.1.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/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +58 -0
- package/.mcp.json +14 -0
- package/README.md +442 -0
- package/dist/__tests__/adf.test.d.ts +1 -0
- package/dist/__tests__/adf.test.js +68 -0
- package/dist/__tests__/adf.test.js.map +1 -0
- package/dist/__tests__/annex-ii-template.test.d.ts +1 -0
- package/dist/__tests__/annex-ii-template.test.js +39 -0
- package/dist/__tests__/annex-ii-template.test.js.map +1 -0
- package/dist/__tests__/doc-render.test.d.ts +1 -0
- package/dist/__tests__/doc-render.test.js +93 -0
- package/dist/__tests__/doc-render.test.js.map +1 -0
- package/dist/__tests__/help.test.d.ts +1 -0
- package/dist/__tests__/help.test.js +31 -0
- package/dist/__tests__/help.test.js.map +1 -0
- package/dist/__tests__/jira-fields.test.d.ts +1 -0
- package/dist/__tests__/jira-fields.test.js +81 -0
- package/dist/__tests__/jira-fields.test.js.map +1 -0
- package/dist/__tests__/plugin-manifest.test.d.ts +1 -0
- package/dist/__tests__/plugin-manifest.test.js +91 -0
- package/dist/__tests__/plugin-manifest.test.js.map +1 -0
- package/dist/__tests__/setup.test.d.ts +1 -0
- package/dist/__tests__/setup.test.js +7 -0
- package/dist/__tests__/setup.test.js.map +1 -0
- package/dist/__tests__/sync-version.test.d.ts +1 -0
- package/dist/__tests__/sync-version.test.js +37 -0
- package/dist/__tests__/sync-version.test.js.map +1 -0
- package/dist/clients/risk-client.d.ts +17 -0
- package/dist/clients/risk-client.js +54 -0
- package/dist/clients/risk-client.js.map +1 -0
- package/dist/clients/xray-client.d.ts +34 -0
- package/dist/clients/xray-client.js +127 -0
- package/dist/clients/xray-client.js.map +1 -0
- package/dist/config/project-config.d.ts +14 -0
- package/dist/config/project-config.js +45 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/confluence-client.d.ts +16 -0
- package/dist/confluence-client.js +97 -0
- package/dist/confluence-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/jira-client.d.ts +35 -0
- package/dist/jira-client.js +119 -0
- package/dist/jira-client.js.map +1 -0
- package/dist/tools/annex-ii-template.d.ts +30 -0
- package/dist/tools/annex-ii-template.js +129 -0
- package/dist/tools/annex-ii-template.js.map +1 -0
- package/dist/tools/confluence.d.ts +2 -0
- package/dist/tools/confluence.js +54 -0
- package/dist/tools/confluence.js.map +1 -0
- package/dist/tools/cvss.d.ts +2 -0
- package/dist/tools/cvss.js +59 -0
- package/dist/tools/cvss.js.map +1 -0
- package/dist/tools/doc-render.d.ts +2 -0
- package/dist/tools/doc-render.js +96 -0
- package/dist/tools/doc-render.js.map +1 -0
- package/dist/tools/doc-validation.d.ts +2 -0
- package/dist/tools/doc-validation.js +221 -0
- package/dist/tools/doc-validation.js.map +1 -0
- package/dist/tools/help-data.d.ts +7 -0
- package/dist/tools/help-data.js +144 -0
- package/dist/tools/help-data.js.map +1 -0
- package/dist/tools/help.d.ts +2 -0
- package/dist/tools/help.js +39 -0
- package/dist/tools/help.js.map +1 -0
- package/dist/tools/iec.d.ts +2 -0
- package/dist/tools/iec.js +203 -0
- package/dist/tools/iec.js.map +1 -0
- package/dist/tools/init.d.ts +2 -0
- package/dist/tools/init.js +38 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/jira-crud.d.ts +2 -0
- package/dist/tools/jira-crud.js +142 -0
- package/dist/tools/jira-crud.js.map +1 -0
- package/dist/tools/risk.d.ts +2 -0
- package/dist/tools/risk.js +172 -0
- package/dist/tools/risk.js.map +1 -0
- package/dist/tools/traceability.d.ts +2 -0
- package/dist/tools/traceability.js +85 -0
- package/dist/tools/traceability.js.map +1 -0
- package/dist/tools/types.d.ts +13 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/usability.d.ts +2 -0
- package/dist/tools/usability.js +149 -0
- package/dist/tools/usability.js.map +1 -0
- package/dist/tools/xray.d.ts +2 -0
- package/dist/tools/xray.js +35 -0
- package/dist/tools/xray.js.map +1 -0
- package/dist/utils/adf.d.ts +27 -0
- package/dist/utils/adf.js +104 -0
- package/dist/utils/adf.js.map +1 -0
- package/dist/utils/cvss.d.ts +15 -0
- package/dist/utils/cvss.js +86 -0
- package/dist/utils/cvss.js.map +1 -0
- package/dist/utils/doc-render.d.ts +28 -0
- package/dist/utils/doc-render.js +50 -0
- package/dist/utils/doc-render.js.map +1 -0
- package/dist/utils/jira-fields.d.ts +38 -0
- package/dist/utils/jira-fields.js +53 -0
- package/dist/utils/jira-fields.js.map +1 -0
- package/dist/utils/sync-version.d.ts +2 -0
- package/dist/utils/sync-version.js +20 -0
- package/dist/utils/sync-version.js.map +1 -0
- package/package.json +49 -0
- package/skills/doc-render/SKILL.md +79 -0
- package/vendor/dev-docs-templates/templates/dev_docs/plan_template.md +104 -0
- package/vendor/dev-docs-templates/templates/dev_docs/prd_template.md +110 -0
- package/vendor/dev-docs-templates/templates/dev_docs/spec_template.md +81 -0
- package/vendor/dev-docs-templates/templates/dev_docs/tasks_template.md +122 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/checklist-clinical-evaluation.md +81 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/checklist-gspr-mdr.md +403 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/clinical-evaluation-report.md +492 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/instructions-for-use.md +132 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/literature-evaluation-table.md +15 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/mdr-declaration-of-conformity.md +75 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/post-market-clinical-follow-up-plan.md +162 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/post-market-surveillance-plan.md +175 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/risk-management-cybersecurity-checklist.md +67 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/risk-management-report.md +111 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/CA/usability-evaluation-report.md +70 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/clinical-evaluation-plan.md +154 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/list-of-hazard-related-use-scenarios.md +34 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/risk-table-fmea.md +155 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/software-architecture-description.md +307 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/software-requirements-list.md +156 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/soup-list.md +82 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/EA/usability-evaluation-plan.md +103 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/global/bug-fixes-documentation-list.md +35 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/global/change-evaluation-list.md +100 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/global/list-of-known-anomalies.md +29 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/algorithm-validation-report.md +170 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/checklist-software-release.md +52 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/checklist-software-requirements-review.md +50 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/software-architecture-checklist.md +41 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/software-detailed-design.md +321 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/software-system-test-plan.md +155 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/ER/sprint/usability-evaluation-protocol.md +63 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/PA/intended-use.md +116 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/PA/mdr-classification-document.md +114 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/PA/risk-management-plan.md +198 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/PA/software-development-maintenance-plan.md +225 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/PA/system-requirements-spec.md +182 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/information_security/information-security-controls.md +966 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/information_security/information-security-policy-and-scope.md +99 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/quality-manual-policy-objectives.md +187 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-capa.md +112 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-change-management.md +128 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-clinical-evaluation.md +102 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-feedback-management.md +140 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-integrated-software-development.md +361 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-post-market-surveillance.md +159 -0
- package/vendor/dev-docs-templates/templates/mdr_docs/global/qms/sop-software-problem-resolution.md +99 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usability.js","sourceRoot":"","sources":["../../src/tools/usability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const registerXrayTools = (ctx) => {
|
|
3
|
+
const { server, xray } = ctx;
|
|
4
|
+
if (!xray)
|
|
5
|
+
return;
|
|
6
|
+
server.tool('xray_get_test_keys', 'Get test case keys from a Test Execution in Xray', {
|
|
7
|
+
test_execution_key: z.string().describe('Test Execution issue key (e.g. PLAYG-2475)'),
|
|
8
|
+
}, async ({ test_execution_key }) => {
|
|
9
|
+
const data = await xray.getTestKeys(test_execution_key);
|
|
10
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
11
|
+
});
|
|
12
|
+
server.tool('xray_export_cucumber', 'Export Cucumber feature files from Xray test cases', {
|
|
13
|
+
keys: z.string().describe('Semicolon-separated test keys (e.g. PLAYG-1;PLAYG-2)'),
|
|
14
|
+
output_dir: z.string().default('./features').describe('Output directory for feature files'),
|
|
15
|
+
}, async ({ keys, output_dir }) => {
|
|
16
|
+
const data = await xray.exportCucumber(keys, output_dir);
|
|
17
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
18
|
+
});
|
|
19
|
+
server.tool('xray_import_results', 'Import test execution results to Xray', {
|
|
20
|
+
results: z.record(z.unknown()).describe('Test execution results in Xray JSON format'),
|
|
21
|
+
}, async ({ results }) => {
|
|
22
|
+
const data = await xray.importResults(results);
|
|
23
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
24
|
+
});
|
|
25
|
+
server.tool('xray_create_test', 'Create a test case in Xray', {
|
|
26
|
+
project_key: z.string().describe('Project key'),
|
|
27
|
+
summary: z.string().describe('Test case summary'),
|
|
28
|
+
gherkin: z.string().optional().describe('Gherkin scenario definition'),
|
|
29
|
+
labels: z.array(z.string()).optional().describe('Labels'),
|
|
30
|
+
}, async ({ project_key, summary, gherkin, labels }) => {
|
|
31
|
+
const data = await xray.createTest(project_key, summary, gherkin, labels);
|
|
32
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=xray.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xray.js","sourceRoot":"","sources":["../../src/tools/xray.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlassian Document Format(ADF) 변환 유틸리티 (순수 함수, I/O 없음).
|
|
3
|
+
* jira-client.ts와 utils/jira-fields.ts 모두가 사용하는 최하위 모듈로,
|
|
4
|
+
* 순환 import를 피하기 위해 분리되었다.
|
|
5
|
+
*/
|
|
6
|
+
export interface AdfDoc {
|
|
7
|
+
type: 'doc';
|
|
8
|
+
version: 1;
|
|
9
|
+
content: Array<{
|
|
10
|
+
type: 'paragraph';
|
|
11
|
+
content: Array<{
|
|
12
|
+
type: 'text';
|
|
13
|
+
text: string;
|
|
14
|
+
}>;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
/** 평문(줄 단위)을 ADF doc으로 변환. 빈 줄은 content가 없는 paragraph가 된다. */
|
|
18
|
+
export declare function textToAdf(text: string): AdfDoc;
|
|
19
|
+
/**
|
|
20
|
+
* ADF 객체를 markdown 평문으로 평탄화.
|
|
21
|
+
* doc_render가 티켓 description/comment를 consumer에게 넘길 때,
|
|
22
|
+
* 중첩 JSON 트리 대신 읽기 쉬운 평문으로 변환하기 위해 사용.
|
|
23
|
+
*
|
|
24
|
+
* 느슨한 타입: Jira 응답은 다양한 block/inline 노드를 포함할 수 있어 any로 받아
|
|
25
|
+
* 안전하게 추출한다. 인식 불가 노드는 텍스트만 추출하거나 무시.
|
|
26
|
+
*/
|
|
27
|
+
export declare function adfToMarkdown(adf: unknown): string;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlassian Document Format(ADF) 변환 유틸리티 (순수 함수, I/O 없음).
|
|
3
|
+
* jira-client.ts와 utils/jira-fields.ts 모두가 사용하는 최하위 모듈로,
|
|
4
|
+
* 순환 import를 피하기 위해 분리되었다.
|
|
5
|
+
*/
|
|
6
|
+
/** 평문(줄 단위)을 ADF doc으로 변환. 빈 줄은 content가 없는 paragraph가 된다. */
|
|
7
|
+
export function textToAdf(text) {
|
|
8
|
+
const paragraphs = text.split('\n').map(line => ({
|
|
9
|
+
type: 'paragraph',
|
|
10
|
+
content: line.trim() ? [{ type: 'text', text: line }] : [],
|
|
11
|
+
}));
|
|
12
|
+
return { type: 'doc', version: 1, content: paragraphs };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* ADF 객체를 markdown 평문으로 평탄화.
|
|
16
|
+
* doc_render가 티켓 description/comment를 consumer에게 넘길 때,
|
|
17
|
+
* 중첩 JSON 트리 대신 읽기 쉬운 평문으로 변환하기 위해 사용.
|
|
18
|
+
*
|
|
19
|
+
* 느슨한 타입: Jira 응답은 다양한 block/inline 노드를 포함할 수 있어 any로 받아
|
|
20
|
+
* 안전하게 추출한다. 인식 불가 노드는 텍스트만 추출하거나 무시.
|
|
21
|
+
*/
|
|
22
|
+
export function adfToMarkdown(adf) {
|
|
23
|
+
if (!adf || typeof adf !== 'object')
|
|
24
|
+
return '';
|
|
25
|
+
const doc = adf;
|
|
26
|
+
const blocks = Array.isArray(doc.content) ? doc.content : [];
|
|
27
|
+
return blocks
|
|
28
|
+
.map(blockToMarkdown)
|
|
29
|
+
.filter(s => s !== '')
|
|
30
|
+
.join('\n\n')
|
|
31
|
+
.trim();
|
|
32
|
+
}
|
|
33
|
+
function blockToMarkdown(block) {
|
|
34
|
+
if (!block || typeof block !== 'object')
|
|
35
|
+
return '';
|
|
36
|
+
switch (block.type) {
|
|
37
|
+
case 'paragraph':
|
|
38
|
+
return inlineToMarkdown(block.content);
|
|
39
|
+
case 'heading': {
|
|
40
|
+
const level = block.attrs?.level || 1;
|
|
41
|
+
return '#'.repeat(Math.min(level, 6)) + ' ' + inlineToMarkdown(block.content);
|
|
42
|
+
}
|
|
43
|
+
case 'bulletList':
|
|
44
|
+
case 'orderedList': {
|
|
45
|
+
const marker = block.type === 'bulletList' ? '- ' : '1. ';
|
|
46
|
+
const items = Array.isArray(block.content) ? block.content : [];
|
|
47
|
+
return items
|
|
48
|
+
.filter(i => i?.type === 'listItem')
|
|
49
|
+
.map(i => {
|
|
50
|
+
// listItem.content는 보통 [paragraph]; 첫 paragraph의 인라인 텍스트 사용
|
|
51
|
+
const para = (i.content || []).find((b) => b?.type === 'paragraph');
|
|
52
|
+
return marker + inlineToMarkdown(para?.content);
|
|
53
|
+
})
|
|
54
|
+
.join('\n');
|
|
55
|
+
}
|
|
56
|
+
case 'codeBlock': {
|
|
57
|
+
const code = (block.content || [])
|
|
58
|
+
.map((c) => (c?.type === 'text' ? c.text || '' : ''))
|
|
59
|
+
.join('');
|
|
60
|
+
return '```\n' + code + '\n```';
|
|
61
|
+
}
|
|
62
|
+
case 'blockquote': {
|
|
63
|
+
const inner = inlineToMarkdown(block.content);
|
|
64
|
+
return inner.split('\n').map(l => '> ' + l).join('\n');
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
// 알 수 없는 block — content에서 텍스트 추출 시도
|
|
68
|
+
return inlineToMarkdown(block.content);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function inlineToMarkdown(content) {
|
|
72
|
+
if (!Array.isArray(content))
|
|
73
|
+
return '';
|
|
74
|
+
return content.map(inlineNodeToMarkdown).join('');
|
|
75
|
+
}
|
|
76
|
+
function inlineNodeToMarkdown(node) {
|
|
77
|
+
if (!node || typeof node !== 'object')
|
|
78
|
+
return '';
|
|
79
|
+
switch (node.type) {
|
|
80
|
+
case 'text': {
|
|
81
|
+
let t = node.text || '';
|
|
82
|
+
const marks = Array.isArray(node.marks) ? node.marks.map((m) => m?.type) : [];
|
|
83
|
+
// code가 먼저(내부 마크 무시), 그 다음 strong/em/strike
|
|
84
|
+
if (marks.includes('code'))
|
|
85
|
+
return '`' + t + '`';
|
|
86
|
+
if (marks.includes('strong'))
|
|
87
|
+
t = '**' + t + '**';
|
|
88
|
+
if (marks.includes('em'))
|
|
89
|
+
t = '*' + t + '*';
|
|
90
|
+
if (marks.includes('strike'))
|
|
91
|
+
t = '~~' + t + '~~';
|
|
92
|
+
return t;
|
|
93
|
+
}
|
|
94
|
+
case 'hardBreak':
|
|
95
|
+
return '\n';
|
|
96
|
+
case 'mention':
|
|
97
|
+
return node.attrs?.text || `@${node.attrs?.id || ''}`;
|
|
98
|
+
case 'emoji':
|
|
99
|
+
return node.attrs?.shortName ? `:${node.attrs.shortName}:` : '';
|
|
100
|
+
default:
|
|
101
|
+
return node.text || '';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=adf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adf.js","sourceRoot":"","sources":["../../src/utils/adf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const BASE_METRICS: readonly ["AV", "AC", "AT", "PR", "UI", "VC", "VI", "VA", "SC", "SI", "SA"];
|
|
2
|
+
declare const SUPPLEMENTAL_METRICS: readonly ["S", "AU", "R", "V", "RE", "U"];
|
|
3
|
+
type BaseMetric = typeof BASE_METRICS[number];
|
|
4
|
+
type SuppMetric = typeof SUPPLEMENTAL_METRICS[number];
|
|
5
|
+
type MetricKey = BaseMetric | SuppMetric;
|
|
6
|
+
declare const METRIC_VALUES: Record<MetricKey, string[]>;
|
|
7
|
+
declare const METRIC_LABELS: Record<MetricKey, string>;
|
|
8
|
+
export declare function parseCvssVector(vector: string): Record<string, string>;
|
|
9
|
+
export declare function buildCvssVector(metrics: Record<string, string>): string;
|
|
10
|
+
export declare function calculateCvssScore(metrics: Record<string, string>): {
|
|
11
|
+
score: number;
|
|
12
|
+
severity: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function validateMetrics(metrics: Record<string, string>): string[];
|
|
15
|
+
export { METRIC_LABELS, METRIC_VALUES, BASE_METRICS, SUPPLEMENTAL_METRICS };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const BASE_METRICS = ['AV', 'AC', 'AT', 'PR', 'UI', 'VC', 'VI', 'VA', 'SC', 'SI', 'SA'];
|
|
2
|
+
const SUPPLEMENTAL_METRICS = ['S', 'AU', 'R', 'V', 'RE', 'U'];
|
|
3
|
+
const METRIC_VALUES = {
|
|
4
|
+
AV: ['N', 'A', 'L', 'P'],
|
|
5
|
+
AC: ['L', 'H'],
|
|
6
|
+
AT: ['N', 'P'],
|
|
7
|
+
PR: ['N', 'L', 'H'],
|
|
8
|
+
UI: ['N', 'P', 'A'],
|
|
9
|
+
VC: ['H', 'L', 'N'],
|
|
10
|
+
VI: ['H', 'L', 'N'],
|
|
11
|
+
VA: ['H', 'L', 'N'],
|
|
12
|
+
SC: ['H', 'L', 'N'],
|
|
13
|
+
SI: ['H', 'L', 'N'],
|
|
14
|
+
SA: ['H', 'L', 'N'],
|
|
15
|
+
S: ['X', 'N', 'P'],
|
|
16
|
+
AU: ['X', 'N', 'Y'],
|
|
17
|
+
R: ['X', 'A', 'U', 'I'],
|
|
18
|
+
V: ['X', 'D', 'C'],
|
|
19
|
+
RE: ['X', 'L', 'M', 'H'],
|
|
20
|
+
U: ['X', 'Clear', 'Green', 'Amber', 'Red'],
|
|
21
|
+
};
|
|
22
|
+
const METRIC_LABELS = {
|
|
23
|
+
AV: 'Attack Vector', AC: 'Attack Complexity', AT: 'Attack Requirements',
|
|
24
|
+
PR: 'Privileges Required', UI: 'User Interaction',
|
|
25
|
+
VC: 'Confidentiality (Vulnerable)', VI: 'Integrity (Vulnerable)', VA: 'Availability (Vulnerable)',
|
|
26
|
+
SC: 'Confidentiality (Subsequent)', SI: 'Integrity (Subsequent)', SA: 'Availability (Subsequent)',
|
|
27
|
+
S: 'Safety', AU: 'Automatable', R: 'Recovery', V: 'Value Density',
|
|
28
|
+
RE: 'Vulnerability Response Effort', U: 'Provider Urgency',
|
|
29
|
+
};
|
|
30
|
+
export function parseCvssVector(vector) {
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const part of vector.split('/')) {
|
|
33
|
+
const colonIdx = part.indexOf(':');
|
|
34
|
+
if (colonIdx > 0) {
|
|
35
|
+
const k = part.substring(0, colonIdx);
|
|
36
|
+
const v = part.substring(colonIdx + 1);
|
|
37
|
+
if (k !== 'CVSS')
|
|
38
|
+
result[k] = v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
export function buildCvssVector(metrics) {
|
|
44
|
+
const base = BASE_METRICS.filter(m => metrics[m]).map(m => `${m}:${metrics[m]}`).join('/');
|
|
45
|
+
const supp = SUPPLEMENTAL_METRICS.filter(m => metrics[m] && metrics[m] !== 'X').map(m => `${m}:${metrics[m]}`).join('/');
|
|
46
|
+
return `CVSS:4.0/${base}${supp ? '/' + supp : ''}`;
|
|
47
|
+
}
|
|
48
|
+
export function calculateCvssScore(metrics) {
|
|
49
|
+
const avScores = { N: 0.2, A: 0.15, L: 0.1, P: 0.05 };
|
|
50
|
+
const acScores = { L: 0.1, H: 0.05 };
|
|
51
|
+
const atScores = { N: 0.1, P: 0.05 };
|
|
52
|
+
const prScores = { N: 0.15, L: 0.1, H: 0.05 };
|
|
53
|
+
const uiScores = { N: 0.1, P: 0.07, A: 0.05 };
|
|
54
|
+
const impactScores = { H: 0.2, L: 0.1, N: 0.0 };
|
|
55
|
+
const exploit = (avScores[metrics.AV ?? 'N'] ?? 0.1) + (acScores[metrics.AC ?? 'L'] ?? 0.05) +
|
|
56
|
+
(atScores[metrics.AT ?? 'N'] ?? 0.1) + (prScores[metrics.PR ?? 'N'] ?? 0.1) + (uiScores[metrics.UI ?? 'N'] ?? 0.1);
|
|
57
|
+
const vulnImpact = (impactScores[metrics.VC ?? 'N'] ?? 0) + (impactScores[metrics.VI ?? 'N'] ?? 0) + (impactScores[metrics.VA ?? 'N'] ?? 0);
|
|
58
|
+
const subImpact = (impactScores[metrics.SC ?? 'N'] ?? 0) + (impactScores[metrics.SI ?? 'N'] ?? 0) + (impactScores[metrics.SA ?? 'N'] ?? 0);
|
|
59
|
+
const score = Math.min(10.0, Math.max(0.0, (exploit + vulnImpact + subImpact) * 10));
|
|
60
|
+
const rounded = Math.round(score * 10) / 10;
|
|
61
|
+
let severity;
|
|
62
|
+
if (rounded === 0)
|
|
63
|
+
severity = 'None';
|
|
64
|
+
else if (rounded < 4.0)
|
|
65
|
+
severity = 'Low';
|
|
66
|
+
else if (rounded < 7.0)
|
|
67
|
+
severity = 'Medium';
|
|
68
|
+
else if (rounded < 9.0)
|
|
69
|
+
severity = 'High';
|
|
70
|
+
else
|
|
71
|
+
severity = 'Critical';
|
|
72
|
+
return { score: rounded, severity };
|
|
73
|
+
}
|
|
74
|
+
export function validateMetrics(metrics) {
|
|
75
|
+
const errors = [];
|
|
76
|
+
for (const [k, v] of Object.entries(metrics)) {
|
|
77
|
+
const valid = METRIC_VALUES[k];
|
|
78
|
+
if (!valid)
|
|
79
|
+
errors.push(`Unknown metric: ${k}`);
|
|
80
|
+
else if (!valid.includes(v))
|
|
81
|
+
errors.push(`Invalid value ${v} for ${k}. Valid: ${valid.join(', ')}`);
|
|
82
|
+
}
|
|
83
|
+
return errors;
|
|
84
|
+
}
|
|
85
|
+
export { METRIC_LABELS, METRIC_VALUES, BASE_METRICS, SUPPLEMENTAL_METRICS };
|
|
86
|
+
//# sourceMappingURL=cvss.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cvss.js","sourceRoot":"","sources":["../../src/utils/cvss.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface TicketMeta {
|
|
2
|
+
key: string;
|
|
3
|
+
issuetype?: string;
|
|
4
|
+
projectName?: string;
|
|
5
|
+
reporter?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RenderInput {
|
|
8
|
+
template: string;
|
|
9
|
+
ticket: TicketMeta;
|
|
10
|
+
featureSlug?: string;
|
|
11
|
+
date: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RenderResult {
|
|
14
|
+
rendered: string;
|
|
15
|
+
unresolved: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function extractVars(template: string): string[];
|
|
18
|
+
export declare function renderTemplate(input: RenderInput): RenderResult;
|
|
19
|
+
export type RenderMode = 'freeform' | 'table-map';
|
|
20
|
+
export interface TemplateEntry {
|
|
21
|
+
path: string;
|
|
22
|
+
mode: RenderMode;
|
|
23
|
+
domain: 'dev' | 'mdr';
|
|
24
|
+
gate?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const TEMPLATE_PATHS: Record<string, TemplateEntry>;
|
|
27
|
+
export declare const TEMPLATE_NAMES: string[];
|
|
28
|
+
export declare const TEMPLATE_VERSION = "4dc0c46";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// dev_docs 템플릿 순수 치환 로직 — I/O 없음, 단위 테스트 대상.
|
|
2
|
+
// 메타 변수(TICKET_ID 등)는 결정적 치환, 그 외 {VAR}는 자유 텍스트로 consumer가 채운다.
|
|
3
|
+
// {VAR} 추출 — 대문자/숫자/언더바만. 소문자·이중괄호 무시.
|
|
4
|
+
const VAR_RE = /\{([A-Z0-9_]+)\}/g;
|
|
5
|
+
export function extractVars(template) {
|
|
6
|
+
const names = new Set();
|
|
7
|
+
let m;
|
|
8
|
+
while ((m = VAR_RE.exec(template)) !== null) {
|
|
9
|
+
names.add(m[1]);
|
|
10
|
+
}
|
|
11
|
+
return [...names];
|
|
12
|
+
}
|
|
13
|
+
// 메타 변수 → 값 매핑표. 이 표에 없는 {VAR}는 자유 텍스트(placeholder 보존).
|
|
14
|
+
const META_RESOLVERS = {
|
|
15
|
+
TICKET_ID: (i) => i.ticket.key,
|
|
16
|
+
ISSUE_TYPE: (i) => i.ticket.issuetype,
|
|
17
|
+
PROJECT_NAME: (i) => i.ticket.projectName,
|
|
18
|
+
AUTHOR: (i) => i.ticket.reporter,
|
|
19
|
+
FEATURE_SLUG: (i) => i.featureSlug,
|
|
20
|
+
DATE: (i) => i.date,
|
|
21
|
+
};
|
|
22
|
+
export function renderTemplate(input) {
|
|
23
|
+
const vars = extractVars(input.template);
|
|
24
|
+
let rendered = input.template;
|
|
25
|
+
const unresolved = [];
|
|
26
|
+
for (const v of vars) {
|
|
27
|
+
const resolver = META_RESOLVERS[v];
|
|
28
|
+
const val = resolver ? resolver(input) : undefined;
|
|
29
|
+
if (val !== undefined && val !== '') {
|
|
30
|
+
rendered = rendered.split(`{${v}}`).join(val);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
unresolved.push(v); // 메타지만 값 없음 OR 자유 텍스트 → placeholder 보존
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { rendered, unresolved };
|
|
37
|
+
}
|
|
38
|
+
export const TEMPLATE_PATHS = {
|
|
39
|
+
prd: { path: 'dev_docs/prd_template.md', mode: 'freeform', domain: 'dev' },
|
|
40
|
+
spec: { path: 'dev_docs/spec_template.md', mode: 'freeform', domain: 'dev' },
|
|
41
|
+
plan: { path: 'dev_docs/plan_template.md', mode: 'freeform', domain: 'dev' },
|
|
42
|
+
tasks: { path: 'dev_docs/tasks_template.md', mode: 'freeform', domain: 'dev' },
|
|
43
|
+
intended_use: { path: 'mdr_docs/PA/intended-use.md', mode: 'freeform', domain: 'mdr', gate: 'PA' },
|
|
44
|
+
};
|
|
45
|
+
export const TEMPLATE_NAMES = Object.keys(TEMPLATE_PATHS);
|
|
46
|
+
// 렌더에 사용된 템플릿 submodule pin(짧은 해시). consumer 산물 frontmatter의
|
|
47
|
+
// template_version에 기록 — Phase 5에서 템플릿 변경 시 재렌더 대상 판별용.
|
|
48
|
+
// submodule 갱신 시 이 값도 함께 갱신: `git submodule status` 앞 7자리.
|
|
49
|
+
export const TEMPLATE_VERSION = '4dc0c46';
|
|
50
|
+
//# sourceMappingURL=doc-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc-render.js","sourceRoot":"","sources":["../../src/utils/doc-render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* customfield의 ADF(Atlassian Document Format) 요구 여부 판별 + 자동 변환 유틸리티.
|
|
3
|
+
*
|
|
4
|
+
* 배경: createmeta의 `schema.type`이 부정확한 경우가 있다 (string으로 보고되지만
|
|
5
|
+
* 실제로는 rich text/ADF를 요구). 이 모듈은 (C) 하이브리드 방식을 제공한다.
|
|
6
|
+
* 1. schema 기반 1차 추정 — inferFieldFormat / inferAdfFields
|
|
7
|
+
* 2. 명시 override — 호출자가 rich_text_custom_fields로 명시
|
|
8
|
+
* 둘을 병합해 최종 ADF 대상 키 집합을 정한다.
|
|
9
|
+
*/
|
|
10
|
+
/** getIssueTypeSchema가 반환하는 필드 메타의 최소 형태. */
|
|
11
|
+
export interface FieldSchemaHint {
|
|
12
|
+
key: string;
|
|
13
|
+
type: string;
|
|
14
|
+
custom?: string;
|
|
15
|
+
inferredFormat?: string;
|
|
16
|
+
allowedValues?: unknown[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 단일 필드의 형식을 추정한다.
|
|
20
|
+
* - 'adf' — type이 doc (확정적 ADF)
|
|
21
|
+
* - 'adf-suspect' — type은 string이나 custom이 textarea (거짓 보고 의심)
|
|
22
|
+
* - 'option' — option 또는 allowedValues가 있는 array
|
|
23
|
+
* - 그 외 — type 그대로 (string, number, date, ...)
|
|
24
|
+
*/
|
|
25
|
+
export declare function inferFieldFormat(type: string, custom?: string, hasAllowedValues?: boolean): string;
|
|
26
|
+
/**
|
|
27
|
+
* schema에서 ADF 대상 키를 추정하고, 명시 키와 병합한다 (중복 제거).
|
|
28
|
+
* adf + adf-suspect 모두 포함. 명시 키는 schema와 무관하게 항상 포함된다.
|
|
29
|
+
*/
|
|
30
|
+
export declare function inferAdfFields(fields: FieldSchemaHint[], explicitKeys?: string[]): string[];
|
|
31
|
+
/**
|
|
32
|
+
* 지정된 키의 값을 ADF로 변환한다.
|
|
33
|
+
* - string → textToAdf 변환
|
|
34
|
+
* - 이미 객체(ADF) / null / undefined → 그대로
|
|
35
|
+
* - 존재하지 않는 키 / 빈 배열 → 무변경
|
|
36
|
+
* 원본 fields를 변이시키지 않는 순수 함수.
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyAdfToFields(fields: Record<string, unknown>, adfKeys: string[]): Record<string, unknown>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { textToAdf } from './adf.js';
|
|
2
|
+
/**
|
|
3
|
+
* 단일 필드의 형식을 추정한다.
|
|
4
|
+
* - 'adf' — type이 doc (확정적 ADF)
|
|
5
|
+
* - 'adf-suspect' — type은 string이나 custom이 textarea (거짓 보고 의심)
|
|
6
|
+
* - 'option' — option 또는 allowedValues가 있는 array
|
|
7
|
+
* - 그 외 — type 그대로 (string, number, date, ...)
|
|
8
|
+
*/
|
|
9
|
+
export function inferFieldFormat(type, custom, hasAllowedValues = false) {
|
|
10
|
+
if (type === 'doc')
|
|
11
|
+
return 'adf';
|
|
12
|
+
if (type === 'string' && custom?.includes('textarea'))
|
|
13
|
+
return 'adf-suspect';
|
|
14
|
+
if (type === 'option')
|
|
15
|
+
return 'option';
|
|
16
|
+
if (type === 'array' && hasAllowedValues)
|
|
17
|
+
return 'option';
|
|
18
|
+
return type;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* schema에서 ADF 대상 키를 추정하고, 명시 키와 병합한다 (중복 제거).
|
|
22
|
+
* adf + adf-suspect 모두 포함. 명시 키는 schema와 무관하게 항상 포함된다.
|
|
23
|
+
*/
|
|
24
|
+
export function inferAdfFields(fields, explicitKeys) {
|
|
25
|
+
const fromSchema = fields
|
|
26
|
+
.filter(f => f.inferredFormat === 'adf' || f.inferredFormat === 'adf-suspect')
|
|
27
|
+
.map(f => f.key);
|
|
28
|
+
const merged = explicitKeys?.length ? [...fromSchema, ...explicitKeys] : fromSchema;
|
|
29
|
+
return Array.from(new Set(merged));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 지정된 키의 값을 ADF로 변환한다.
|
|
33
|
+
* - string → textToAdf 변환
|
|
34
|
+
* - 이미 객체(ADF) / null / undefined → 그대로
|
|
35
|
+
* - 존재하지 않는 키 / 빈 배열 → 무변경
|
|
36
|
+
* 원본 fields를 변이시키지 않는 순수 함수.
|
|
37
|
+
*/
|
|
38
|
+
export function applyAdfToFields(fields, adfKeys) {
|
|
39
|
+
if (!adfKeys.length)
|
|
40
|
+
return fields;
|
|
41
|
+
const result = { ...fields };
|
|
42
|
+
for (const key of adfKeys) {
|
|
43
|
+
if (!(key in result))
|
|
44
|
+
continue;
|
|
45
|
+
const val = result[key];
|
|
46
|
+
if (typeof val === 'string') {
|
|
47
|
+
result[key] = textToAdf(val);
|
|
48
|
+
}
|
|
49
|
+
// 객체(이미 ADF) 등은 그대로 둔다.
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=jira-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jira-fields.js","sourceRoot":"","sources":["../../src/utils/jira-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAqBrC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAe,EAAE,gBAAgB,GAAG,KAAK;IACtF,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,IAAI,KAAK,QAAQ,IAAI,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,aAAa,CAAC;IAC5E,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACvC,IAAI,IAAI,KAAK,OAAO,IAAI,gBAAgB;QAAE,OAAO,QAAQ,CAAC;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,EAAE,YAAuB;IAC/E,MAAM,UAAU,GAAG,MAAM;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,KAAK,IAAI,CAAC,CAAC,cAAc,KAAK,aAAa,CAAC;SAC7E,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,MAAM,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACpF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA+B,EAAE,OAAiB;IACjF,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IACnC,MAAM,MAAM,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACtD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QACD,wBAAwB;IAC1B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// package.json version을 plugin.json/marketplace.json에 주입하는 순수 함수 (I/O 없음).
|
|
2
|
+
// 2-space 들여쓰기 + 후행 줄바꿈 유지 (기존 매니페스트 파일 포맷과 일치).
|
|
3
|
+
const stringify = (obj) => JSON.stringify(obj, null, 2) + '\n';
|
|
4
|
+
export function injectPluginVersion(pluginJson, version) {
|
|
5
|
+
const obj = JSON.parse(pluginJson);
|
|
6
|
+
obj.version = version;
|
|
7
|
+
return stringify(obj);
|
|
8
|
+
}
|
|
9
|
+
export function injectMarketplaceVersion(marketplaceJson, version) {
|
|
10
|
+
const obj = JSON.parse(marketplaceJson);
|
|
11
|
+
if (!Array.isArray(obj.plugins) || obj.plugins.length === 0) {
|
|
12
|
+
throw new Error('marketplace.json must have at least one plugin entry');
|
|
13
|
+
}
|
|
14
|
+
if (!obj.plugins[0].source || typeof obj.plugins[0].source !== 'object') {
|
|
15
|
+
obj.plugins[0].source = {};
|
|
16
|
+
}
|
|
17
|
+
obj.plugins[0].source.version = version;
|
|
18
|
+
return stringify(obj);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=sync-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-version.js","sourceRoot":"","sources":["../../src/utils/sync-version.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iDAAiD;AAEjD,MAAM,SAAS,GAAG,CAAC,GAAY,EAAU,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAEhF,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,OAAe;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACnC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACtB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,eAAuB,EAAE,OAAe;IAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;IAC7B,CAAC;IACD,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACxC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neobiotechlabs/neobiotech-dev-agent",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "Jira & Confluence MCP Server for Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"neobiotech-dev-agent": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"prepublishOnly": "npm run build && node scripts/sync-plugin-version.mjs"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"jira",
|
|
21
|
+
"confluence",
|
|
22
|
+
"claude-code"
|
|
23
|
+
],
|
|
24
|
+
"author": "NeoBiotech",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"vendor/dev-docs-templates/templates",
|
|
29
|
+
".claude-plugin",
|
|
30
|
+
"skills",
|
|
31
|
+
".mcp.json"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"registry": "https://registry.npmjs.org",
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
39
|
+
"adm-zip": "^0.5.17",
|
|
40
|
+
"node-fetch": "^3.3.2",
|
|
41
|
+
"zod": "^3.24.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/adm-zip": "^0.5.8",
|
|
45
|
+
"@types/node": "^22.0.0",
|
|
46
|
+
"typescript": "^5.7.0",
|
|
47
|
+
"vitest": "^4.1.6"
|
|
48
|
+
}
|
|
49
|
+
}
|