@iloom/cli 0.9.2 → 0.10.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.
- package/LICENSE +1 -1
- package/README.md +159 -40
- package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-ECJHBB67.js} +2 -2
- package/dist/ClaudeContextManager-QXX6ZFST.js +14 -0
- package/dist/ClaudeService-NJNK2SUH.js +13 -0
- package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
- package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
- package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-L64HHS3T.js} +9 -9
- package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
- package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
- package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-DULSVRRE.js} +2 -2
- package/dist/README.md +159 -40
- package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-BQDQA3FK.js} +4 -2
- package/dist/agents/iloom-artifact-reviewer.md +11 -0
- package/dist/agents/iloom-code-reviewer.md +14 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
- package/dist/agents/iloom-issue-analyzer.md +49 -6
- package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
- package/dist/agents/iloom-issue-enhancer.md +86 -7
- package/dist/agents/iloom-issue-implementer.md +48 -7
- package/dist/agents/iloom-issue-planner.md +115 -62
- package/dist/{build-THZI572G.js → build-5GO3XW26.js} +9 -9
- package/dist/{chunk-NUACL52E.js → chunk-3D7WQM7I.js} +2 -2
- package/dist/chunk-4232AHNQ.js +35 -0
- package/dist/chunk-4232AHNQ.js.map +1 -0
- package/dist/{chunk-QN47QVBX.js → chunk-4WJNIR5O.js} +1 -1
- package/dist/chunk-4WJNIR5O.js.map +1 -0
- package/dist/{chunk-A7NJF73J.js → chunk-5MWV33NN.js} +4 -4
- package/dist/{chunk-3I4ONZRT.js → chunk-6EU6TCF6.js} +10 -10
- package/dist/chunk-6EU6TCF6.js.map +1 -0
- package/dist/{chunk-CWRI4JC3.js → chunk-FB47TIJG.js} +29 -11
- package/dist/chunk-FB47TIJG.js.map +1 -0
- package/dist/chunk-HEXKPKCK.js +1396 -0
- package/dist/chunk-HEXKPKCK.js.map +1 -0
- package/dist/{chunk-KAYXR544.js → chunk-J5S7DFYC.js} +2 -2
- package/dist/{chunk-ULSWCPQG.js → chunk-JO2LZ6EQ.js} +476 -5
- package/dist/chunk-JO2LZ6EQ.js.map +1 -0
- package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
- package/dist/chunk-KB64WNBZ.js.map +1 -0
- package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
- package/dist/chunk-KXDRI47U.js.map +1 -0
- package/dist/{chunk-R4YWBGY6.js → chunk-LXLMMXXY.js} +54 -14
- package/dist/chunk-LXLMMXXY.js.map +1 -0
- package/dist/{chunk-AR5QKYNE.js → chunk-MNHZB4Z2.js} +4 -4
- package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
- package/dist/{chunk-KJTVU3HZ.js → chunk-NRSWLOAZ.js} +8 -8
- package/dist/chunk-NRSWLOAZ.js.map +1 -0
- package/dist/{chunk-FO5GGFOV.js → chunk-ONQYPICO.js} +13 -5
- package/dist/chunk-ONQYPICO.js.map +1 -0
- package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
- package/dist/chunk-QZWEJVWV.js +207 -0
- package/dist/chunk-QZWEJVWV.js.map +1 -0
- package/dist/chunk-RSYT7MVI.js +202 -0
- package/dist/chunk-RSYT7MVI.js.map +1 -0
- package/dist/{chunk-Z2TWEXR7.js → chunk-RYWFS37M.js} +6 -6
- package/dist/chunk-RYWFS37M.js.map +1 -0
- package/dist/{chunk-B7U6OKUR.js → chunk-SF2P22EE.js} +11 -3
- package/dist/chunk-SF2P22EE.js.map +1 -0
- package/dist/{chunk-6IIL5M2L.js → chunk-SN3SQCFK.js} +10 -8
- package/dist/{chunk-6IIL5M2L.js.map → chunk-SN3SQCFK.js.map} +1 -1
- package/dist/{chunk-SOSQILHO.js → chunk-UD3WJDIV.js} +92 -82
- package/dist/chunk-UD3WJDIV.js.map +1 -0
- package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
- package/dist/chunk-UKBAJ2QQ.js.map +1 -0
- package/dist/{chunk-W6DP5RVR.js → chunk-UVD4CZKS.js} +3 -3
- package/dist/chunk-UWGVCXRF.js +207 -0
- package/dist/chunk-UWGVCXRF.js.map +1 -0
- package/dist/{chunk-NWMORW3U.js → chunk-VECNX6VX.js} +2 -2
- package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
- package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
- package/dist/{chunk-TC7APDKU.js → chunk-VGGST52X.js} +2 -2
- package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
- package/dist/{chunk-YKFCCV6S.js → chunk-WY4QBK43.js} +7 -7
- package/dist/chunk-WY4QBK43.js.map +1 -0
- package/dist/chunk-Y4YZTHZE.js +73 -0
- package/dist/chunk-Y4YZTHZE.js.map +1 -0
- package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
- package/dist/chunk-YQ57ORTV.js.map +1 -0
- package/dist/{chunk-RI2YL6TK.js → chunk-YYAKPQBT.js} +65 -18
- package/dist/chunk-YYAKPQBT.js.map +1 -0
- package/dist/{chunk-IZIYLYPK.js → chunk-ZEWU5PZK.js} +2 -2
- package/dist/{chunk-VPTAX5TR.js → chunk-ZHPNZC75.js} +12 -12
- package/dist/chunk-ZHPNZC75.js.map +1 -0
- package/dist/{chunk-DGG2VY7B.js → chunk-ZW2LKWWE.js} +9 -9
- package/dist/chunk-ZW2LKWWE.js.map +1 -0
- package/dist/{claude-TP2QO3BU.js → claude-P3NQR6IJ.js} +2 -2
- package/dist/{cleanup-PJRIFFU4.js → cleanup-6UCPVMFG.js} +81 -32
- package/dist/cleanup-6UCPVMFG.js.map +1 -0
- package/dist/cli.js +638 -349
- package/dist/cli.js.map +1 -1
- package/dist/{commit-IVP3M4HG.js → commit-L3EPY5QG.js} +21 -20
- package/dist/commit-L3EPY5QG.js.map +1 -0
- package/dist/{compile-R2J65HBQ.js → compile-ZS4HYRX5.js} +9 -9
- package/dist/{contribute-VDZXHK5Y.js → contribute-ORDDQGSL.js} +14 -6
- package/dist/contribute-ORDDQGSL.js.map +1 -0
- package/dist/{dev-server-7F622OEO.js → dev-server-FYZ2AQIH.js} +29 -15
- package/dist/dev-server-FYZ2AQIH.js.map +1 -0
- package/dist/{feedback-E7VET7CL.js → feedback-TMBXSCM5.js} +15 -15
- package/dist/{git-2QDQ2X2S.js → git-ET64COO3.js} +4 -4
- package/dist/hooks/iloom-hook.js +15 -0
- package/dist/ignite-CGOV3TD4.js +1393 -0
- package/dist/ignite-CGOV3TD4.js.map +1 -0
- package/dist/index.d.ts +382 -53
- package/dist/index.js +1167 -36
- package/dist/index.js.map +1 -1
- package/dist/{init-676DHF6R.js → init-GFQ5W7GK.js} +57 -21
- package/dist/init-GFQ5W7GK.js.map +1 -0
- package/dist/{issues-PJSOLOBJ.js → issues-T4ZZSPEG.js} +61 -20
- package/dist/issues-T4ZZSPEG.js.map +1 -0
- package/dist/{lint-CJM7BAIM.js → lint-6TQXDZ3T.js} +9 -9
- package/dist/mcp/issue-management-server.js +2471 -256
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/recap-server.js +144 -21
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
- package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
- package/dist/{open-544H7JF5.js → open-5QZGXQRF.js} +15 -15
- package/dist/open-5QZGXQRF.js.map +1 -0
- package/dist/{plan-Q7ELXDLC.js → plan-U7ZQWLFY.js} +41 -25
- package/dist/plan-U7ZQWLFY.js.map +1 -0
- package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
- package/dist/prompts/CLAUDE.md +62 -0
- package/dist/prompts/init-prompt.txt +347 -26
- package/dist/prompts/issue-prompt.txt +427 -54
- package/dist/prompts/plan-prompt.txt +97 -16
- package/dist/prompts/pr-prompt.txt +44 -1
- package/dist/prompts/regular-prompt.txt +42 -1
- package/dist/prompts/session-summary-prompt.txt +14 -0
- package/dist/prompts/swarm-orchestrator-prompt.txt +437 -0
- package/dist/{rebase-YND35CIE.js → rebase-DWIB77KV.js} +10 -10
- package/dist/{recap-3W7COH7D.js → recap-MX63HAKV.js} +47 -19
- package/dist/recap-MX63HAKV.js.map +1 -0
- package/dist/{run-QUXJKDQQ.js → run-O3TFNQFC.js} +15 -15
- package/dist/run-O3TFNQFC.js.map +1 -0
- package/dist/schema/package-iloom.schema.json +58 -0
- package/dist/schema/settings.schema.json +115 -15
- package/dist/{shell-QGECBLST.js → shell-G6VC2CYR.js} +14 -7
- package/dist/shell-G6VC2CYR.js.map +1 -0
- package/dist/{summary-G2T4452H.js → summary-FWHAX55O.js} +27 -25
- package/dist/summary-FWHAX55O.js.map +1 -0
- package/dist/{test-EA5NQFDC.js → test-F7JNJZYP.js} +9 -9
- package/dist/{test-git-M7LSLEFL.js → test-git-BTAOIUE2.js} +4 -4
- package/dist/test-jira-CHYNV33F.js +96 -0
- package/dist/test-jira-CHYNV33F.js.map +1 -0
- package/dist/{test-prefix-64NAAUON.js → test-prefix-Q6TFSU6F.js} +4 -4
- package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-EONCG7E7.js} +6 -6
- package/dist/{vscode-AR5NNXXI.js → vscode-VA5X4P25.js} +7 -7
- package/package.json +5 -1
- package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
- package/dist/ClaudeService-TK7FMC2X.js +0 -13
- package/dist/chunk-3I4ONZRT.js.map +0 -1
- package/dist/chunk-B7U6OKUR.js.map +0 -1
- package/dist/chunk-CWRI4JC3.js.map +0 -1
- package/dist/chunk-DGG2VY7B.js.map +0 -1
- package/dist/chunk-FJDRTVJX.js +0 -520
- package/dist/chunk-FJDRTVJX.js.map +0 -1
- package/dist/chunk-FO5GGFOV.js.map +0 -1
- package/dist/chunk-KBEIQP4G.js.map +0 -1
- package/dist/chunk-KJTVU3HZ.js.map +0 -1
- package/dist/chunk-KXGQYLFZ.js.map +0 -1
- package/dist/chunk-OFDN5NKS.js.map +0 -1
- package/dist/chunk-QN47QVBX.js.map +0 -1
- package/dist/chunk-R4YWBGY6.js.map +0 -1
- package/dist/chunk-RI2YL6TK.js.map +0 -1
- package/dist/chunk-SOSQILHO.js.map +0 -1
- package/dist/chunk-ULSWCPQG.js.map +0 -1
- package/dist/chunk-VOGGLPG5.js.map +0 -1
- package/dist/chunk-VPTAX5TR.js.map +0 -1
- package/dist/chunk-WHI5KEOX.js +0 -121
- package/dist/chunk-WHI5KEOX.js.map +0 -1
- package/dist/chunk-YKFCCV6S.js.map +0 -1
- package/dist/chunk-Z2TWEXR7.js.map +0 -1
- package/dist/cleanup-PJRIFFU4.js.map +0 -1
- package/dist/commit-IVP3M4HG.js.map +0 -1
- package/dist/contribute-VDZXHK5Y.js.map +0 -1
- package/dist/dev-server-7F622OEO.js.map +0 -1
- package/dist/ignite-IW35CDBD.js +0 -784
- package/dist/ignite-IW35CDBD.js.map +0 -1
- package/dist/init-676DHF6R.js.map +0 -1
- package/dist/issues-PJSOLOBJ.js.map +0 -1
- package/dist/open-544H7JF5.js.map +0 -1
- package/dist/plan-Q7ELXDLC.js.map +0 -1
- package/dist/recap-3W7COH7D.js.map +0 -1
- package/dist/run-QUXJKDQQ.js.map +0 -1
- package/dist/shell-QGECBLST.js.map +0 -1
- package/dist/summary-G2T4452H.js.map +0 -1
- /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-ECJHBB67.js.map} +0 -0
- /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-QXX6ZFST.js.map} +0 -0
- /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-NJNK2SUH.js.map} +0 -0
- /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
- /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
- /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-L64HHS3T.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
- /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
- /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-DULSVRRE.js.map} +0 -0
- /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-BQDQA3FK.js.map} +0 -0
- /package/dist/{build-THZI572G.js.map → build-5GO3XW26.js.map} +0 -0
- /package/dist/{chunk-NUACL52E.js.map → chunk-3D7WQM7I.js.map} +0 -0
- /package/dist/{chunk-A7NJF73J.js.map → chunk-5MWV33NN.js.map} +0 -0
- /package/dist/{chunk-KAYXR544.js.map → chunk-J5S7DFYC.js.map} +0 -0
- /package/dist/{chunk-AR5QKYNE.js.map → chunk-MNHZB4Z2.js.map} +0 -0
- /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
- /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
- /package/dist/{chunk-W6DP5RVR.js.map → chunk-UVD4CZKS.js.map} +0 -0
- /package/dist/{chunk-NWMORW3U.js.map → chunk-VECNX6VX.js.map} +0 -0
- /package/dist/{chunk-TC7APDKU.js.map → chunk-VGGST52X.js.map} +0 -0
- /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
- /package/dist/{chunk-IZIYLYPK.js.map → chunk-ZEWU5PZK.js.map} +0 -0
- /package/dist/{git-2QDQ2X2S.js.map → claude-P3NQR6IJ.js.map} +0 -0
- /package/dist/{compile-R2J65HBQ.js.map → compile-ZS4HYRX5.js.map} +0 -0
- /package/dist/{feedback-E7VET7CL.js.map → feedback-TMBXSCM5.js.map} +0 -0
- /package/dist/{neon-helpers-VVFFTLXE.js.map → git-ET64COO3.js.map} +0 -0
- /package/dist/{lint-CJM7BAIM.js.map → lint-6TQXDZ3T.js.map} +0 -0
- /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
- /package/dist/{rebase-YND35CIE.js.map → rebase-DWIB77KV.js.map} +0 -0
- /package/dist/{test-EA5NQFDC.js.map → test-F7JNJZYP.js.map} +0 -0
- /package/dist/{test-git-M7LSLEFL.js.map → test-git-BTAOIUE2.js.map} +0 -0
- /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-Q6TFSU6F.js.map} +0 -0
- /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-EONCG7E7.js.map} +0 -0
- /package/dist/{vscode-AR5NNXXI.js.map → vscode-VA5X4P25.js.map} +0 -0
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
escapeJql
|
|
4
|
+
} from "./chunk-4232AHNQ.js";
|
|
5
|
+
import {
|
|
6
|
+
SettingsManager
|
|
7
|
+
} from "./chunk-YYAKPQBT.js";
|
|
8
|
+
import {
|
|
9
|
+
JiraIssueTracker,
|
|
3
10
|
createLinearChildIssue,
|
|
4
11
|
createLinearComment,
|
|
5
12
|
createLinearIssue,
|
|
6
13
|
createLinearIssueRelation,
|
|
7
14
|
deleteLinearIssueRelation,
|
|
15
|
+
editLinearIssue,
|
|
8
16
|
fetchLinearIssue,
|
|
9
17
|
fetchLinearIssueComments,
|
|
10
18
|
findLinearIssueRelation,
|
|
11
19
|
getLinearChildIssues,
|
|
12
20
|
getLinearComment,
|
|
13
21
|
getLinearIssueDependencies,
|
|
14
|
-
updateLinearComment
|
|
15
|
-
|
|
22
|
+
updateLinearComment,
|
|
23
|
+
updateLinearIssueState
|
|
24
|
+
} from "./chunk-HEXKPKCK.js";
|
|
16
25
|
import {
|
|
17
26
|
addSubIssue,
|
|
27
|
+
closeGhIssue,
|
|
18
28
|
createIssue,
|
|
19
29
|
createIssueComment,
|
|
20
30
|
createIssueDependency,
|
|
21
31
|
createPRComment,
|
|
32
|
+
editGhIssue,
|
|
22
33
|
executeGhCommand,
|
|
23
34
|
getIssueDatabaseId,
|
|
24
35
|
getIssueDependencies,
|
|
25
36
|
getIssueNodeId,
|
|
26
37
|
getSubIssues,
|
|
27
38
|
removeIssueDependency,
|
|
39
|
+
reopenGhIssue,
|
|
28
40
|
updateIssueComment
|
|
29
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-VG45TUYK.js";
|
|
30
42
|
import {
|
|
31
43
|
logger
|
|
32
44
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -429,6 +441,55 @@ var GitHubIssueManagementProvider = class {
|
|
|
429
441
|
}
|
|
430
442
|
return result;
|
|
431
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* Fetch PR review comments (inline code comments on specific files/lines)
|
|
446
|
+
* Uses gh api with --paginate to handle PRs with many review comments
|
|
447
|
+
* Optionally filters by review ID
|
|
448
|
+
*/
|
|
449
|
+
async getReviewComments(input) {
|
|
450
|
+
const { number, reviewId, repo } = input;
|
|
451
|
+
const prNumber = parseInt(number, 10);
|
|
452
|
+
if (isNaN(prNumber)) {
|
|
453
|
+
throw new Error(`Invalid GitHub PR number: ${number}. GitHub PR IDs must be numeric.`);
|
|
454
|
+
}
|
|
455
|
+
let numericReviewId;
|
|
456
|
+
if (reviewId) {
|
|
457
|
+
numericReviewId = parseInt(reviewId, 10);
|
|
458
|
+
if (isNaN(numericReviewId)) {
|
|
459
|
+
throw new Error(`Invalid review ID: ${reviewId}. Review IDs must be numeric.`);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const apiPath = repo ? `repos/${repo}/pulls/${prNumber}/comments` : `repos/:owner/:repo/pulls/${prNumber}/comments`;
|
|
463
|
+
const args = [
|
|
464
|
+
"api",
|
|
465
|
+
apiPath,
|
|
466
|
+
"--paginate",
|
|
467
|
+
"--jq",
|
|
468
|
+
"[.[] | {id: .id, body: .body, path: .path, line: .line, side: .side, user: .user, created_at: .created_at, updated_at: .updated_at, in_reply_to_id: .in_reply_to_id, pull_request_review_id: .pull_request_review_id}]"
|
|
469
|
+
];
|
|
470
|
+
const raw = await executeGhCommand(args);
|
|
471
|
+
let comments = raw;
|
|
472
|
+
if (numericReviewId !== void 0) {
|
|
473
|
+
comments = comments.filter((c) => c.pull_request_review_id === numericReviewId);
|
|
474
|
+
}
|
|
475
|
+
const results = [];
|
|
476
|
+
for (const comment of comments) {
|
|
477
|
+
const processedBody = await processMarkdownImages(comment.body, "github");
|
|
478
|
+
results.push({
|
|
479
|
+
id: String(comment.id),
|
|
480
|
+
body: processedBody,
|
|
481
|
+
path: comment.path,
|
|
482
|
+
line: comment.line,
|
|
483
|
+
side: comment.side,
|
|
484
|
+
author: normalizeAuthor(comment.user),
|
|
485
|
+
createdAt: comment.created_at,
|
|
486
|
+
updatedAt: comment.updated_at ?? null,
|
|
487
|
+
inReplyToId: comment.in_reply_to_id ? String(comment.in_reply_to_id) : null,
|
|
488
|
+
pullRequestReviewId: comment.pull_request_review_id
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return results;
|
|
492
|
+
}
|
|
432
493
|
/**
|
|
433
494
|
* Fetch a specific comment by ID using gh API
|
|
434
495
|
* Normalizes author to FlexibleAuthor format
|
|
@@ -588,6 +649,55 @@ var GitHubIssueManagementProvider = class {
|
|
|
588
649
|
}
|
|
589
650
|
return await getSubIssues(issueNumber, repo);
|
|
590
651
|
}
|
|
652
|
+
/**
|
|
653
|
+
* Close an issue
|
|
654
|
+
*/
|
|
655
|
+
async closeIssue(input) {
|
|
656
|
+
const { number, repo } = input;
|
|
657
|
+
const issueNumber = parseInt(number, 10);
|
|
658
|
+
if (isNaN(issueNumber)) {
|
|
659
|
+
throw new Error(`Invalid GitHub issue number: ${number}. GitHub issue IDs must be numeric.`);
|
|
660
|
+
}
|
|
661
|
+
await closeGhIssue(issueNumber, repo);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Reopen a closed issue
|
|
665
|
+
*/
|
|
666
|
+
async reopenIssue(input) {
|
|
667
|
+
const { number, repo } = input;
|
|
668
|
+
const issueNumber = parseInt(number, 10);
|
|
669
|
+
if (isNaN(issueNumber)) {
|
|
670
|
+
throw new Error(`Invalid GitHub issue number: ${number}. GitHub issue IDs must be numeric.`);
|
|
671
|
+
}
|
|
672
|
+
await reopenGhIssue(issueNumber, repo);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Edit an issue's properties
|
|
676
|
+
* State changes are delegated to closeIssue/reopenIssue
|
|
677
|
+
*/
|
|
678
|
+
async editIssue(input) {
|
|
679
|
+
const { number, title, body, state, labels, repo } = input;
|
|
680
|
+
const issueNumber = parseInt(number, 10);
|
|
681
|
+
if (isNaN(issueNumber)) {
|
|
682
|
+
throw new Error(`Invalid GitHub issue number: ${number}. GitHub issue IDs must be numeric.`);
|
|
683
|
+
}
|
|
684
|
+
if (state === "closed") {
|
|
685
|
+
await this.closeIssue({ number, repo });
|
|
686
|
+
} else if (state === "open") {
|
|
687
|
+
await this.reopenIssue({ number, repo });
|
|
688
|
+
}
|
|
689
|
+
if (title !== void 0 || body !== void 0 || labels !== void 0) {
|
|
690
|
+
await editGhIssue(
|
|
691
|
+
issueNumber,
|
|
692
|
+
{
|
|
693
|
+
...title !== void 0 && { title },
|
|
694
|
+
...body !== void 0 && { body },
|
|
695
|
+
...labels !== void 0 && { labels }
|
|
696
|
+
},
|
|
697
|
+
repo
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
591
701
|
};
|
|
592
702
|
|
|
593
703
|
// src/utils/linear-markup-converter.ts
|
|
@@ -940,19 +1050,380 @@ var LinearIssueManagementProvider = class {
|
|
|
940
1050
|
const { number } = input;
|
|
941
1051
|
return await getLinearChildIssues(number);
|
|
942
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Close an issue by transitioning to "Done" state
|
|
1055
|
+
*/
|
|
1056
|
+
async closeIssue(input) {
|
|
1057
|
+
const { number } = input;
|
|
1058
|
+
await updateLinearIssueState(number, "Done");
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Reopen a closed issue by transitioning to "Todo" state
|
|
1062
|
+
*/
|
|
1063
|
+
async reopenIssue(input) {
|
|
1064
|
+
const { number } = input;
|
|
1065
|
+
await updateLinearIssueState(number, "Todo");
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Edit an issue's properties
|
|
1069
|
+
* State changes are delegated to closeIssue/reopenIssue
|
|
1070
|
+
*/
|
|
1071
|
+
async editIssue(input) {
|
|
1072
|
+
const { number, title, body, state } = input;
|
|
1073
|
+
if (state === "closed") {
|
|
1074
|
+
await this.closeIssue({ number });
|
|
1075
|
+
} else if (state === "open") {
|
|
1076
|
+
await this.reopenIssue({ number });
|
|
1077
|
+
}
|
|
1078
|
+
if (title !== void 0 || body !== void 0) {
|
|
1079
|
+
await editLinearIssue(number, {
|
|
1080
|
+
...title !== void 0 && { title },
|
|
1081
|
+
...body !== void 0 && { description: body }
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
// src/mcp/JiraIssueManagementProvider.ts
|
|
1088
|
+
function normalizeAuthor2(author) {
|
|
1089
|
+
if (!author) return null;
|
|
1090
|
+
return {
|
|
1091
|
+
id: author.accountId ?? author.emailAddress ?? "unknown",
|
|
1092
|
+
displayName: author.displayName ?? author.emailAddress ?? "Unknown",
|
|
1093
|
+
...author.emailAddress && { email: author.emailAddress },
|
|
1094
|
+
...author.accountId && { accountId: author.accountId }
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
var getJiraTrackerConfig = (settings) => {
|
|
1098
|
+
var _a;
|
|
1099
|
+
const jiraSettings = (_a = settings.issueManagement) == null ? void 0 : _a.jira;
|
|
1100
|
+
if ((jiraSettings == null ? void 0 : jiraSettings.host) && (jiraSettings == null ? void 0 : jiraSettings.username) && (jiraSettings == null ? void 0 : jiraSettings.apiToken) && (jiraSettings == null ? void 0 : jiraSettings.projectKey)) {
|
|
1101
|
+
const config = {
|
|
1102
|
+
host: jiraSettings.host,
|
|
1103
|
+
username: jiraSettings.username,
|
|
1104
|
+
apiToken: jiraSettings.apiToken,
|
|
1105
|
+
projectKey: jiraSettings.projectKey
|
|
1106
|
+
};
|
|
1107
|
+
if (jiraSettings.transitionMappings) {
|
|
1108
|
+
config.transitionMappings = jiraSettings.transitionMappings;
|
|
1109
|
+
}
|
|
1110
|
+
if (jiraSettings.defaultIssueType) {
|
|
1111
|
+
config.defaultIssueType = jiraSettings.defaultIssueType;
|
|
1112
|
+
}
|
|
1113
|
+
if (jiraSettings.defaultSubtaskType) {
|
|
1114
|
+
config.defaultSubtaskType = jiraSettings.defaultSubtaskType;
|
|
1115
|
+
}
|
|
1116
|
+
return config;
|
|
1117
|
+
}
|
|
1118
|
+
if (process.env.JIRA_HOST && process.env.JIRA_USERNAME && process.env.JIRA_API_TOKEN && process.env.JIRA_PROJECT_KEY) {
|
|
1119
|
+
const config = {
|
|
1120
|
+
host: process.env.JIRA_HOST,
|
|
1121
|
+
username: process.env.JIRA_USERNAME,
|
|
1122
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
1123
|
+
projectKey: process.env.JIRA_PROJECT_KEY
|
|
1124
|
+
};
|
|
1125
|
+
if (process.env.JIRA_TRANSITION_MAPPINGS) {
|
|
1126
|
+
try {
|
|
1127
|
+
config.transitionMappings = JSON.parse(process.env.JIRA_TRANSITION_MAPPINGS);
|
|
1128
|
+
} catch {
|
|
1129
|
+
throw new Error("Invalid JSON in JIRA_TRANSITION_MAPPINGS environment variable");
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (process.env.JIRA_DEFAULT_ISSUE_TYPE) {
|
|
1133
|
+
config.defaultIssueType = process.env.JIRA_DEFAULT_ISSUE_TYPE;
|
|
1134
|
+
}
|
|
1135
|
+
if (process.env.JIRA_DEFAULT_SUBTASK_TYPE) {
|
|
1136
|
+
config.defaultSubtaskType = process.env.JIRA_DEFAULT_SUBTASK_TYPE;
|
|
1137
|
+
}
|
|
1138
|
+
return config;
|
|
1139
|
+
}
|
|
1140
|
+
throw new Error(
|
|
1141
|
+
"Missing required Jira settings: issueManagement.jira.{host, username, apiToken, projectKey} or corresponding environment variables"
|
|
1142
|
+
);
|
|
1143
|
+
};
|
|
1144
|
+
var JiraIssueManagementProvider = class _JiraIssueManagementProvider {
|
|
1145
|
+
constructor(settings) {
|
|
1146
|
+
this.providerName = "jira";
|
|
1147
|
+
this.issuePrefix = "";
|
|
1148
|
+
const config = getJiraTrackerConfig(settings);
|
|
1149
|
+
this.tracker = new JiraIssueTracker(config);
|
|
1150
|
+
this.projectKey = config.projectKey;
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Static factory for convenience when settings aren't pre-loaded
|
|
1154
|
+
*/
|
|
1155
|
+
static async create() {
|
|
1156
|
+
const settingsManager = new SettingsManager();
|
|
1157
|
+
const settings = await settingsManager.loadSettings();
|
|
1158
|
+
return new _JiraIssueManagementProvider(settings);
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Fetch issue details using JiraIssueTracker
|
|
1162
|
+
*/
|
|
1163
|
+
async getIssue(input) {
|
|
1164
|
+
const { number, includeComments = true } = input;
|
|
1165
|
+
const issue = await this.tracker.getIssue(number);
|
|
1166
|
+
const issueExt = issue;
|
|
1167
|
+
const result = {
|
|
1168
|
+
id: issueExt.id ?? String(issue.number),
|
|
1169
|
+
title: issue.title,
|
|
1170
|
+
body: issue.body,
|
|
1171
|
+
state: issue.state,
|
|
1172
|
+
url: issue.url,
|
|
1173
|
+
provider: "jira",
|
|
1174
|
+
author: normalizeAuthor2(issueExt.author),
|
|
1175
|
+
number: issue.number,
|
|
1176
|
+
key: issueExt.key,
|
|
1177
|
+
// Preserve Jira-specific fields
|
|
1178
|
+
...issueExt.issueType && { issueType: issueExt.issueType },
|
|
1179
|
+
...issueExt.priority && { priority: issueExt.priority },
|
|
1180
|
+
...issueExt.status && { status: issueExt.status }
|
|
1181
|
+
};
|
|
1182
|
+
if (issue.labels && issue.labels.length > 0) {
|
|
1183
|
+
result.labels = issue.labels.map((label) => ({ name: label }));
|
|
1184
|
+
}
|
|
1185
|
+
if (issue.assignees && issue.assignees.length > 0) {
|
|
1186
|
+
result.assignees = issue.assignees.map((name) => ({
|
|
1187
|
+
id: name,
|
|
1188
|
+
displayName: name
|
|
1189
|
+
}));
|
|
1190
|
+
}
|
|
1191
|
+
if (includeComments) {
|
|
1192
|
+
const comments = await this.tracker.getComments(number);
|
|
1193
|
+
result.comments = comments.map((comment) => ({
|
|
1194
|
+
id: comment.id,
|
|
1195
|
+
body: comment.body,
|
|
1196
|
+
author: normalizeAuthor2(comment.author),
|
|
1197
|
+
createdAt: comment.createdAt,
|
|
1198
|
+
updatedAt: comment.updatedAt
|
|
1199
|
+
}));
|
|
1200
|
+
}
|
|
1201
|
+
return result;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Fetch a specific comment by ID
|
|
1205
|
+
*/
|
|
1206
|
+
async getComment(input) {
|
|
1207
|
+
const { commentId, number } = input;
|
|
1208
|
+
const comments = await this.tracker.getComments(number);
|
|
1209
|
+
const comment = comments.find((c) => c.id === commentId);
|
|
1210
|
+
if (!comment) {
|
|
1211
|
+
throw new Error(`Comment ${commentId} not found on issue ${number}`);
|
|
1212
|
+
}
|
|
1213
|
+
return {
|
|
1214
|
+
id: comment.id,
|
|
1215
|
+
body: comment.body,
|
|
1216
|
+
author: normalizeAuthor2(comment.author),
|
|
1217
|
+
created_at: comment.createdAt,
|
|
1218
|
+
updated_at: comment.updatedAt
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Create a new comment on an issue
|
|
1223
|
+
*/
|
|
1224
|
+
async createComment(input) {
|
|
1225
|
+
const { number, body } = input;
|
|
1226
|
+
const normalizedKey = this.tracker.normalizeIdentifier(number);
|
|
1227
|
+
const comment = await this.tracker.addComment(normalizedKey, body);
|
|
1228
|
+
return {
|
|
1229
|
+
id: comment.id,
|
|
1230
|
+
url: `${this.tracker.getConfig().host}/browse/${normalizedKey}?focusedCommentId=${comment.id}`,
|
|
1231
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Update an existing comment
|
|
1236
|
+
*/
|
|
1237
|
+
async updateComment(input) {
|
|
1238
|
+
const { commentId, number, body } = input;
|
|
1239
|
+
const normalizedKey = this.tracker.normalizeIdentifier(number);
|
|
1240
|
+
await this.tracker.updateComment(normalizedKey, commentId, body);
|
|
1241
|
+
return {
|
|
1242
|
+
id: commentId,
|
|
1243
|
+
url: `${this.tracker.getConfig().host}/browse/${normalizedKey}?focusedCommentId=${commentId}`,
|
|
1244
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Create a new issue
|
|
1249
|
+
*/
|
|
1250
|
+
async createIssue(input) {
|
|
1251
|
+
const { title, body } = input;
|
|
1252
|
+
const issue = await this.tracker.createIssue(title, body);
|
|
1253
|
+
const result = {
|
|
1254
|
+
id: String(issue.number),
|
|
1255
|
+
url: issue.url
|
|
1256
|
+
};
|
|
1257
|
+
if (typeof issue.number === "number") {
|
|
1258
|
+
result.number = issue.number;
|
|
1259
|
+
}
|
|
1260
|
+
return result;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Fetch pull request details
|
|
1264
|
+
* Jira does not have pull requests - throw like Linear does
|
|
1265
|
+
*/
|
|
1266
|
+
async getPR(_input) {
|
|
1267
|
+
throw new Error(
|
|
1268
|
+
"Jira does not support pull requests. PRs exist only on GitHub. Use the GitHub provider for PR operations."
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Create a child issue linked to a parent issue
|
|
1273
|
+
* Uses Jira's parent field to create a subtask
|
|
1274
|
+
*/
|
|
1275
|
+
async createChildIssue(input) {
|
|
1276
|
+
const { parentId, title, body } = input;
|
|
1277
|
+
const parentKey = this.tracker.normalizeIdentifier(parentId);
|
|
1278
|
+
const jiraIssue = await this.tracker.getApiClient().createIssueWithParent(
|
|
1279
|
+
this.projectKey,
|
|
1280
|
+
title,
|
|
1281
|
+
body,
|
|
1282
|
+
parentKey,
|
|
1283
|
+
this.tracker.getConfig().defaultSubtaskType
|
|
1284
|
+
);
|
|
1285
|
+
return {
|
|
1286
|
+
id: jiraIssue.key,
|
|
1287
|
+
url: `${this.tracker.getConfig().host}/browse/${jiraIssue.key}`
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Create a blocking dependency between two issues
|
|
1292
|
+
* Uses Jira issue links with "Blocks" link type
|
|
1293
|
+
*/
|
|
1294
|
+
async createDependency(input) {
|
|
1295
|
+
const blockingKey = this.tracker.normalizeIdentifier(input.blockingIssue);
|
|
1296
|
+
const blockedKey = this.tracker.normalizeIdentifier(input.blockedIssue);
|
|
1297
|
+
await this.tracker.getApiClient().createIssueLink(blockingKey, blockedKey, "Blocks");
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Get dependencies for an issue
|
|
1301
|
+
* Parses issue links of type "Blocks"
|
|
1302
|
+
*/
|
|
1303
|
+
async getDependencies(input) {
|
|
1304
|
+
const issueKey = this.tracker.normalizeIdentifier(input.number);
|
|
1305
|
+
const host = this.tracker.getConfig().host;
|
|
1306
|
+
const issue = await this.tracker.getApiClient().getIssue(issueKey);
|
|
1307
|
+
const links = issue.fields.issuelinks ?? [];
|
|
1308
|
+
const blocking = [];
|
|
1309
|
+
const blockedBy = [];
|
|
1310
|
+
for (const link of links) {
|
|
1311
|
+
if (link.type.name !== "Blocks") continue;
|
|
1312
|
+
if (link.inwardIssue) {
|
|
1313
|
+
blockedBy.push({
|
|
1314
|
+
id: link.inwardIssue.key,
|
|
1315
|
+
title: link.inwardIssue.fields.summary,
|
|
1316
|
+
url: `${host}/browse/${link.inwardIssue.key}`,
|
|
1317
|
+
state: link.inwardIssue.fields.status.name.toLowerCase()
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
if (link.outwardIssue) {
|
|
1321
|
+
blocking.push({
|
|
1322
|
+
id: link.outwardIssue.key,
|
|
1323
|
+
title: link.outwardIssue.fields.summary,
|
|
1324
|
+
url: `${host}/browse/${link.outwardIssue.key}`,
|
|
1325
|
+
state: link.outwardIssue.fields.status.name.toLowerCase()
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
if (input.direction === "blocking") {
|
|
1330
|
+
return { blocking, blockedBy: [] };
|
|
1331
|
+
}
|
|
1332
|
+
if (input.direction === "blocked_by") {
|
|
1333
|
+
return { blocking: [], blockedBy };
|
|
1334
|
+
}
|
|
1335
|
+
return { blocking, blockedBy };
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Remove a blocking dependency between two issues
|
|
1339
|
+
* Finds the matching "Blocks" link and deletes it
|
|
1340
|
+
*/
|
|
1341
|
+
async removeDependency(input) {
|
|
1342
|
+
const blockingKey = this.tracker.normalizeIdentifier(input.blockingIssue);
|
|
1343
|
+
const blockedKey = this.tracker.normalizeIdentifier(input.blockedIssue);
|
|
1344
|
+
const issue = await this.tracker.getApiClient().getIssue(blockedKey);
|
|
1345
|
+
const links = issue.fields.issuelinks ?? [];
|
|
1346
|
+
const matchingLink = links.find(
|
|
1347
|
+
(link) => {
|
|
1348
|
+
var _a;
|
|
1349
|
+
return link.type.name === "Blocks" && ((_a = link.inwardIssue) == null ? void 0 : _a.key) === blockingKey;
|
|
1350
|
+
}
|
|
1351
|
+
);
|
|
1352
|
+
if (!matchingLink) {
|
|
1353
|
+
throw new Error(
|
|
1354
|
+
`No "Blocks" dependency found from ${blockingKey} to ${blockedKey}`
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
await this.tracker.getApiClient().deleteIssueLink(matchingLink.id);
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Get child issues of a parent issue
|
|
1361
|
+
* Uses JQL search: parent = KEY
|
|
1362
|
+
*/
|
|
1363
|
+
async getChildIssues(input) {
|
|
1364
|
+
const parentKey = this.tracker.normalizeIdentifier(input.number);
|
|
1365
|
+
const host = this.tracker.getConfig().host;
|
|
1366
|
+
const issues = await this.tracker.getApiClient().searchIssues(`parent = "${escapeJql(parentKey)}"`);
|
|
1367
|
+
return issues.map((issue) => ({
|
|
1368
|
+
id: issue.key,
|
|
1369
|
+
title: issue.fields.summary,
|
|
1370
|
+
url: `${host}/browse/${issue.key}`,
|
|
1371
|
+
state: issue.fields.status.name.toLowerCase()
|
|
1372
|
+
}));
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Close an issue by transitioning to "Done" state
|
|
1376
|
+
*/
|
|
1377
|
+
async closeIssue(input) {
|
|
1378
|
+
const issueKey = this.tracker.normalizeIdentifier(input.number);
|
|
1379
|
+
await this.tracker.closeIssue(issueKey);
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* Reopen a closed issue
|
|
1383
|
+
*/
|
|
1384
|
+
async reopenIssue(input) {
|
|
1385
|
+
const issueKey = this.tracker.normalizeIdentifier(input.number);
|
|
1386
|
+
await this.tracker.reopenIssue(issueKey);
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Edit an issue's properties
|
|
1390
|
+
* State changes are delegated to closeIssue/reopenIssue
|
|
1391
|
+
*/
|
|
1392
|
+
async editIssue(input) {
|
|
1393
|
+
const { number, title, body, state } = input;
|
|
1394
|
+
if (state === "closed") {
|
|
1395
|
+
await this.closeIssue({ number });
|
|
1396
|
+
} else if (state === "open") {
|
|
1397
|
+
await this.reopenIssue({ number });
|
|
1398
|
+
}
|
|
1399
|
+
if (title !== void 0 || body !== void 0) {
|
|
1400
|
+
const issueKey = this.tracker.normalizeIdentifier(number);
|
|
1401
|
+
await this.tracker.getApiClient().updateIssue(issueKey, {
|
|
1402
|
+
...title !== void 0 && { summary: title },
|
|
1403
|
+
...body !== void 0 && { description: body }
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
943
1407
|
};
|
|
944
1408
|
|
|
945
1409
|
// src/mcp/IssueManagementProviderFactory.ts
|
|
946
1410
|
var IssueManagementProviderFactory = class {
|
|
947
1411
|
/**
|
|
948
1412
|
* Create an issue management provider based on the provider type
|
|
1413
|
+
* @param provider - The provider type (github, linear, jira)
|
|
1414
|
+
* @param settings - Required for Jira provider, optional for others
|
|
949
1415
|
*/
|
|
950
|
-
static create(provider) {
|
|
1416
|
+
static create(provider, settings) {
|
|
951
1417
|
switch (provider) {
|
|
952
1418
|
case "github":
|
|
953
1419
|
return new GitHubIssueManagementProvider();
|
|
954
1420
|
case "linear":
|
|
955
1421
|
return new LinearIssueManagementProvider();
|
|
1422
|
+
case "jira":
|
|
1423
|
+
if (!settings) {
|
|
1424
|
+
throw new Error("Settings required for Jira provider");
|
|
1425
|
+
}
|
|
1426
|
+
return new JiraIssueManagementProvider(settings);
|
|
956
1427
|
default:
|
|
957
1428
|
throw new Error(`Unsupported issue management provider: ${provider}`);
|
|
958
1429
|
}
|
|
@@ -962,4 +1433,4 @@ var IssueManagementProviderFactory = class {
|
|
|
962
1433
|
export {
|
|
963
1434
|
IssueManagementProviderFactory
|
|
964
1435
|
};
|
|
965
|
-
//# sourceMappingURL=chunk-
|
|
1436
|
+
//# sourceMappingURL=chunk-JO2LZ6EQ.js.map
|