@xurenxiang1219/pingcode-mcp 0.3.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/.env.example +115 -0
- package/.env.stdio.local.example +13 -0
- package/README.md +222 -0
- package/dist/approve-write.d.ts +3 -0
- package/dist/approve-write.d.ts.map +1 -0
- package/dist/approve-write.js +81 -0
- package/dist/approve-write.js.map +1 -0
- package/dist/auth/cimd-client-resolver.d.ts +35 -0
- package/dist/auth/cimd-client-resolver.d.ts.map +1 -0
- package/dist/auth/cimd-client-resolver.js +293 -0
- package/dist/auth/cimd-client-resolver.js.map +1 -0
- package/dist/auth/memory-store.d.ts +15 -0
- package/dist/auth/memory-store.d.ts.map +1 -0
- package/dist/auth/memory-store.js +46 -0
- package/dist/auth/memory-store.js.map +1 -0
- package/dist/auth/pingcode-oauth-client.d.ts +23 -0
- package/dist/auth/pingcode-oauth-client.d.ts.map +1 -0
- package/dist/auth/pingcode-oauth-client.js +103 -0
- package/dist/auth/pingcode-oauth-client.js.map +1 -0
- package/dist/auth/pingcode-oauth-provider.d.ts +70 -0
- package/dist/auth/pingcode-oauth-provider.d.ts.map +1 -0
- package/dist/auth/pingcode-oauth-provider.js +414 -0
- package/dist/auth/pingcode-oauth-provider.js.map +1 -0
- package/dist/auth/redis-store.d.ts +16 -0
- package/dist/auth/redis-store.d.ts.map +1 -0
- package/dist/auth/redis-store.js +54 -0
- package/dist/auth/redis-store.js.map +1 -0
- package/dist/auth/runtime.d.ts +10 -0
- package/dist/auth/runtime.d.ts.map +1 -0
- package/dist/auth/runtime.js +57 -0
- package/dist/auth/runtime.js.map +1 -0
- package/dist/auth/store.d.ts +35 -0
- package/dist/auth/store.d.ts.map +1 -0
- package/dist/auth/store.js +55 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/auth/token-cipher.d.ts +7 -0
- package/dist/auth/token-cipher.d.ts.map +1 -0
- package/dist/auth/token-cipher.js +36 -0
- package/dist/auth/token-cipher.js.map +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +270 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/content-hash.d.ts +5 -0
- package/dist/domain/content-hash.d.ts.map +1 -0
- package/dist/domain/content-hash.js +17 -0
- package/dist/domain/content-hash.js.map +1 -0
- package/dist/domain/requirement-context.d.ts +29 -0
- package/dist/domain/requirement-context.d.ts.map +1 -0
- package/dist/domain/requirement-context.js +2 -0
- package/dist/domain/requirement-context.js.map +1 -0
- package/dist/domain/test-case-context.d.ts +56 -0
- package/dist/domain/test-case-context.d.ts.map +1 -0
- package/dist/domain/test-case-context.js +2 -0
- package/dist/domain/test-case-context.js.map +1 -0
- package/dist/domain/work-item-context.d.ts +47 -0
- package/dist/domain/work-item-context.d.ts.map +1 -0
- package/dist/domain/work-item-context.js +2 -0
- package/dist/domain/work-item-context.js.map +1 -0
- package/dist/environment.d.ts +2 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +21 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-wiki.d.ts +3 -0
- package/dist/inspect-wiki.d.ts.map +1 -0
- package/dist/inspect-wiki.js +49 -0
- package/dist/inspect-wiki.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/create-server.d.ts +10 -0
- package/dist/mcp/create-server.d.ts.map +1 -0
- package/dist/mcp/create-server.js +40 -0
- package/dist/mcp/create-server.js.map +1 -0
- package/dist/mcp/pagination-guidance.d.ts +19 -0
- package/dist/mcp/pagination-guidance.d.ts.map +1 -0
- package/dist/mcp/pagination-guidance.js +36 -0
- package/dist/mcp/pagination-guidance.js.map +1 -0
- package/dist/mcp/reference-resolution.d.ts +19 -0
- package/dist/mcp/reference-resolution.d.ts.map +1 -0
- package/dist/mcp/reference-resolution.js +160 -0
- package/dist/mcp/reference-resolution.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +2 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +55 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tool-runtime.d.ts +22 -0
- package/dist/mcp/tool-runtime.d.ts.map +1 -0
- package/dist/mcp/tool-runtime.js +214 -0
- package/dist/mcp/tool-runtime.js.map +1 -0
- package/dist/mcp/tools/member-role.d.ts +8 -0
- package/dist/mcp/tools/member-role.d.ts.map +1 -0
- package/dist/mcp/tools/member-role.js +451 -0
- package/dist/mcp/tools/member-role.js.map +1 -0
- package/dist/mcp/tools/metadata.d.ts +5 -0
- package/dist/mcp/tools/metadata.d.ts.map +1 -0
- package/dist/mcp/tools/metadata.js +606 -0
- package/dist/mcp/tools/metadata.js.map +1 -0
- package/dist/mcp/tools/project-context.d.ts +4 -0
- package/dist/mcp/tools/project-context.d.ts.map +1 -0
- package/dist/mcp/tools/project-context.js +111 -0
- package/dist/mcp/tools/project-context.js.map +1 -0
- package/dist/mcp/tools/project.d.ts +7 -0
- package/dist/mcp/tools/project.d.ts.map +1 -0
- package/dist/mcp/tools/project.js +370 -0
- package/dist/mcp/tools/project.js.map +1 -0
- package/dist/mcp/tools/relation.d.ts +7 -0
- package/dist/mcp/tools/relation.d.ts.map +1 -0
- package/dist/mcp/tools/relation.js +592 -0
- package/dist/mcp/tools/relation.js.map +1 -0
- package/dist/mcp/tools/runtime-info.d.ts +4 -0
- package/dist/mcp/tools/runtime-info.d.ts.map +1 -0
- package/dist/mcp/tools/runtime-info.js +49 -0
- package/dist/mcp/tools/runtime-info.js.map +1 -0
- package/dist/mcp/tools/ship-suite.d.ts +7 -0
- package/dist/mcp/tools/ship-suite.d.ts.map +1 -0
- package/dist/mcp/tools/ship-suite.js +636 -0
- package/dist/mcp/tools/ship-suite.js.map +1 -0
- package/dist/mcp/tools/ship.d.ts +7 -0
- package/dist/mcp/tools/ship.d.ts.map +1 -0
- package/dist/mcp/tools/ship.js +617 -0
- package/dist/mcp/tools/ship.js.map +1 -0
- package/dist/mcp/tools/sync.d.ts +10 -0
- package/dist/mcp/tools/sync.d.ts.map +1 -0
- package/dist/mcp/tools/sync.js +1110 -0
- package/dist/mcp/tools/sync.js.map +1 -0
- package/dist/mcp/tools/task.d.ts +5 -0
- package/dist/mcp/tools/task.d.ts.map +1 -0
- package/dist/mcp/tools/task.js +236 -0
- package/dist/mcp/tools/task.js.map +1 -0
- package/dist/mcp/tools/test-case-bulk.d.ts +7 -0
- package/dist/mcp/tools/test-case-bulk.d.ts.map +1 -0
- package/dist/mcp/tools/test-case-bulk.js +297 -0
- package/dist/mcp/tools/test-case-bulk.js.map +1 -0
- package/dist/mcp/tools/test-case-delete.d.ts +7 -0
- package/dist/mcp/tools/test-case-delete.d.ts.map +1 -0
- package/dist/mcp/tools/test-case-delete.js +247 -0
- package/dist/mcp/tools/test-case-delete.js.map +1 -0
- package/dist/mcp/tools/test-case.d.ts +5 -0
- package/dist/mcp/tools/test-case.d.ts.map +1 -0
- package/dist/mcp/tools/test-case.js +155 -0
- package/dist/mcp/tools/test-case.js.map +1 -0
- package/dist/mcp/tools/test-library.d.ts +7 -0
- package/dist/mcp/tools/test-library.d.ts.map +1 -0
- package/dist/mcp/tools/test-library.js +302 -0
- package/dist/mcp/tools/test-library.js.map +1 -0
- package/dist/mcp/tools/wiki.d.ts +5 -0
- package/dist/mcp/tools/wiki.d.ts.map +1 -0
- package/dist/mcp/tools/wiki.js +266 -0
- package/dist/mcp/tools/wiki.js.map +1 -0
- package/dist/mcp/write-approval.d.ts +48 -0
- package/dist/mcp/write-approval.d.ts.map +1 -0
- package/dist/mcp/write-approval.js +321 -0
- package/dist/mcp/write-approval.js.map +1 -0
- package/dist/observability/metrics.d.ts +46 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +79 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/pingcode/access-token-provider.d.ts +5 -0
- package/dist/pingcode/access-token-provider.d.ts.map +1 -0
- package/dist/pingcode/access-token-provider.js +2 -0
- package/dist/pingcode/access-token-provider.js.map +1 -0
- package/dist/pingcode/client.d.ts +43 -0
- package/dist/pingcode/client.d.ts.map +1 -0
- package/dist/pingcode/client.js +300 -0
- package/dist/pingcode/client.js.map +1 -0
- package/dist/pingcode/errors.d.ts +20 -0
- package/dist/pingcode/errors.d.ts.map +1 -0
- package/dist/pingcode/errors.js +14 -0
- package/dist/pingcode/errors.js.map +1 -0
- package/dist/pingcode/schemas.d.ts +465 -0
- package/dist/pingcode/schemas.d.ts.map +1 -0
- package/dist/pingcode/schemas.js +450 -0
- package/dist/pingcode/schemas.js.map +1 -0
- package/dist/pingcode/token-provider.d.ts +20 -0
- package/dist/pingcode/token-provider.d.ts.map +1 -0
- package/dist/pingcode/token-provider.js +97 -0
- package/dist/pingcode/token-provider.js.map +1 -0
- package/dist/pingcode/write-response.d.ts +9 -0
- package/dist/pingcode/write-response.d.ts.map +1 -0
- package/dist/pingcode/write-response.js +39 -0
- package/dist/pingcode/write-response.js.map +1 -0
- package/dist/services.d.ts +22 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +84 -0
- package/dist/services.js.map +1 -0
- package/dist/sources/metadata-source.d.ts +445 -0
- package/dist/sources/metadata-source.d.ts.map +1 -0
- package/dist/sources/metadata-source.js +167 -0
- package/dist/sources/metadata-source.js.map +1 -0
- package/dist/sources/project-context-source.d.ts +61 -0
- package/dist/sources/project-context-source.d.ts.map +1 -0
- package/dist/sources/project-context-source.js +224 -0
- package/dist/sources/project-context-source.js.map +1 -0
- package/dist/sources/relation-source.d.ts +83 -0
- package/dist/sources/relation-source.d.ts.map +1 -0
- package/dist/sources/relation-source.js +129 -0
- package/dist/sources/relation-source.js.map +1 -0
- package/dist/sources/requirement-source.d.ts +5 -0
- package/dist/sources/requirement-source.d.ts.map +1 -0
- package/dist/sources/requirement-source.js +2 -0
- package/dist/sources/requirement-source.js.map +1 -0
- package/dist/sources/ship-source.d.ts +67 -0
- package/dist/sources/ship-source.d.ts.map +1 -0
- package/dist/sources/ship-source.js +135 -0
- package/dist/sources/ship-source.js.map +1 -0
- package/dist/sources/test-case-source.d.ts +30 -0
- package/dist/sources/test-case-source.d.ts.map +1 -0
- package/dist/sources/test-case-source.js +206 -0
- package/dist/sources/test-case-source.js.map +1 -0
- package/dist/sources/wiki-source.d.ts +34 -0
- package/dist/sources/wiki-source.d.ts.map +1 -0
- package/dist/sources/wiki-source.js +136 -0
- package/dist/sources/wiki-source.js.map +1 -0
- package/dist/sources/work-item-source.d.ts +33 -0
- package/dist/sources/work-item-source.d.ts.map +1 -0
- package/dist/sources/work-item-source.js +159 -0
- package/dist/sources/work-item-source.js.map +1 -0
- package/dist/sources/write-source.d.ts +461 -0
- package/dist/sources/write-source.d.ts.map +1 -0
- package/dist/sources/write-source.js +174 -0
- package/dist/sources/write-source.js.map +1 -0
- package/dist/transports/bearer-auth.d.ts +20 -0
- package/dist/transports/bearer-auth.d.ts.map +1 -0
- package/dist/transports/bearer-auth.js +79 -0
- package/dist/transports/bearer-auth.js.map +1 -0
- package/dist/transports/http.d.ts +11 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +203 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/metrics-auth.d.ts +3 -0
- package/dist/transports/metrics-auth.d.ts.map +1 -0
- package/dist/transports/metrics-auth.js +22 -0
- package/dist/transports/metrics-auth.js.map +1 -0
- package/dist/transports/stdio.d.ts +5 -0
- package/dist/transports/stdio.d.ts.map +1 -0
- package/dist/transports/stdio.js +11 -0
- package/dist/transports/stdio.js.map +1 -0
- package/dist/uat/run-label.d.ts +2 -0
- package/dist/uat/run-label.d.ts.map +1 -0
- package/dist/uat/run-label.js +12 -0
- package/dist/uat/run-label.js.map +1 -0
- package/dist/verify.d.ts +3 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +59 -0
- package/dist/verify.js.map +1 -0
- package/dist/write/approval.d.ts +35 -0
- package/dist/write/approval.d.ts.map +1 -0
- package/dist/write/approval.js +66 -0
- package/dist/write/approval.js.map +1 -0
- package/dist/write/plan.d.ts +2 -0
- package/dist/write/plan.d.ts.map +1 -0
- package/dist/write/plan.js +17 -0
- package/dist/write/plan.js.map +1 -0
- package/dist/write/runtime.d.ts +90 -0
- package/dist/write/runtime.d.ts.map +1 -0
- package/dist/write/runtime.js +244 -0
- package/dist/write/runtime.js.map +1 -0
- package/dist/write/store.d.ts +101 -0
- package/dist/write/store.d.ts.map +1 -0
- package/dist/write/store.js +201 -0
- package/dist/write/store.js.map +1 -0
- package/package.json +58 -0
package/.env.example
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# 完整設定參考。Docker Compose 本機 User OAuth 請優先複製 .env.compose.local.example,
|
|
2
|
+
# 不需要在此填滿所有選項。
|
|
3
|
+
|
|
4
|
+
# PingCode API 基礎地址。
|
|
5
|
+
# 公有雲保持預設值;私有部署或企業閘道請改成客戶提供的地址。
|
|
6
|
+
PINGCODE_API_BASE_URL=https://open.pingcode.com
|
|
7
|
+
|
|
8
|
+
# PingCode OAuth 瀏覽器授權頁根地址,不是 REST API 根地址。
|
|
9
|
+
# 公有雲固定包含 /oauth2;私有部署通常為 https://自訂域名/oauth2。
|
|
10
|
+
PINGCODE_OAUTH_BASE_URL=https://open.pingcode.com/oauth2
|
|
11
|
+
|
|
12
|
+
# 認證模式:
|
|
13
|
+
# - enterprise:使用企業 Client Credentials,可搭配 stdio 或 HTTP。
|
|
14
|
+
# - user_oauth:每位使用者登入 PingCode,只支援 Streamable HTTP。
|
|
15
|
+
PINGCODE_AUTH_MODE=enterprise
|
|
16
|
+
|
|
17
|
+
# PingCode 應用的 Client ID;請由 Secret Manager 或本機 .env 提供實際值。
|
|
18
|
+
PINGCODE_CLIENT_ID=replace-with-client-id
|
|
19
|
+
|
|
20
|
+
# PingCode 應用的 Client Secret;不得提交實際值到 Git。
|
|
21
|
+
PINGCODE_CLIENT_SECRET=replace-with-client-secret
|
|
22
|
+
|
|
23
|
+
# 單次 PingCode API/OAuth 請求逾時,單位毫秒;允許範圍 1000~120000。
|
|
24
|
+
PINGCODE_REQUEST_TIMEOUT_MS=10000
|
|
25
|
+
|
|
26
|
+
# 單次 PingCode API 響應大小上限,單位 bytes;預設 1 MiB。
|
|
27
|
+
PINGCODE_MAX_RESPONSE_BYTES=1048576
|
|
28
|
+
|
|
29
|
+
# 唯讀 API 的最大重試次數;只重試網路錯誤、逾時、429、5xx 及一次 401 Token 刷新。
|
|
30
|
+
PINGCODE_MAX_RETRIES=2
|
|
31
|
+
|
|
32
|
+
# 指數退避的基礎與最大等待時間,單位毫秒;429 會優先遵守 Retry-After,但仍受最大值限制。
|
|
33
|
+
PINGCODE_RETRY_BASE_DELAY_MS=250
|
|
34
|
+
PINGCODE_RETRY_MAX_DELAY_MS=2000
|
|
35
|
+
|
|
36
|
+
# MCP HTTP Server 綁定地址。
|
|
37
|
+
# 本機可用 localhost/127.0.0.1;遠端部署通常使用 0.0.0.0。
|
|
38
|
+
MCP_HOST=127.0.0.1
|
|
39
|
+
|
|
40
|
+
# MCP HTTP Server 監聽埠。
|
|
41
|
+
MCP_PORT=3000
|
|
42
|
+
|
|
43
|
+
# 是否允許綁定非本機地址。
|
|
44
|
+
# 只有 MCP_HOST 使用非本機地址時才設為 true。
|
|
45
|
+
MCP_ALLOW_REMOTE=false
|
|
46
|
+
|
|
47
|
+
# 允許的 HTTP Host,逗號分隔。
|
|
48
|
+
# 本機可留空;遠端應填公開域名,例如 mcp.example.com。
|
|
49
|
+
MCP_ALLOWED_HOSTS=
|
|
50
|
+
|
|
51
|
+
# user_oauth 必填:MCP 對 Client 公開的 origin,不包含 /mcp。
|
|
52
|
+
# 本機範例與 PingCode callback:
|
|
53
|
+
# MCP_PUBLIC_BASE_URL=http://localhost:3000
|
|
54
|
+
# callback=http://localhost:3000/auth/pingcode/callback
|
|
55
|
+
MCP_PUBLIC_BASE_URL=
|
|
56
|
+
|
|
57
|
+
# OAuth 狀態儲存方式:
|
|
58
|
+
# - memory:只供本機 UAT。
|
|
59
|
+
# - redis:正式/多 instance 部署必須使用。
|
|
60
|
+
MCP_OAUTH_STORE=memory
|
|
61
|
+
|
|
62
|
+
# 使用 redis Store 時必填;應由 Secret Manager 注入,不要提交真實密碼。
|
|
63
|
+
MCP_OAUTH_REDIS_URL=
|
|
64
|
+
|
|
65
|
+
# 是否優先支援 OAuth Client ID Metadata Documents;不支援 CIMD 的 Client 仍回退 DCR。
|
|
66
|
+
MCP_OAUTH_CIMD_ENABLED=true
|
|
67
|
+
|
|
68
|
+
# 選填:允許取得 CIMD metadata 的 HTTPS host,逗號分隔;留空表示允許所有公網 host。
|
|
69
|
+
# 企業部署可依 UAT 結果限制,例如:client.example.com,another-client.example.com
|
|
70
|
+
MCP_OAUTH_CIMD_ALLOWED_HOSTS=
|
|
71
|
+
|
|
72
|
+
# DCR fallback Client 註冊有效期,單位秒;預設 365 天,允許範圍 1 天至 2 年。
|
|
73
|
+
MCP_OAUTH_DCR_CLIENT_TTL_SECONDS=31536000
|
|
74
|
+
|
|
75
|
+
# user_oauth 必填:Base64 編碼的 32-byte AES 加密金鑰。
|
|
76
|
+
# 本機可執行:openssl rand -base64 32
|
|
77
|
+
MCP_OAUTH_ENCRYPTION_KEY=replace-with-output-of-openssl-rand-base64-32
|
|
78
|
+
|
|
79
|
+
# MCP Access Token 有效期,單位秒;允許範圍 300~86400。
|
|
80
|
+
MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS=3600
|
|
81
|
+
|
|
82
|
+
# MCP Refresh Token/OAuth Session 有效期,單位秒;預設 30 天。
|
|
83
|
+
MCP_OAUTH_REFRESH_TOKEN_TTL_SECONDS=2592000
|
|
84
|
+
|
|
85
|
+
# 是否啟用本機程序級 JSON Metrics endpoint:GET /metrics。
|
|
86
|
+
# 預設關閉;正式環境只應供監控系統經內網或 Gateway 存取。
|
|
87
|
+
MCP_METRICS_ENABLED=false
|
|
88
|
+
|
|
89
|
+
# Metrics 專用 Bearer Token;啟用時至少 32 字元,必須由 Secret Manager 注入。
|
|
90
|
+
# 不得重用 PingCode Token、MCP OAuth Token 或 Client Secret。
|
|
91
|
+
MCP_METRICS_BEARER_TOKEN=
|
|
92
|
+
|
|
93
|
+
# Server 是否要求 MCP Client 顯示 Commit 確認。即使免確認,仍執行 Preview、Approval、request hash、
|
|
94
|
+
# session binding、幂等與 Audit Log。可選 required(預設)、update、delete 或 none。
|
|
95
|
+
PINGCODE_WRITE_CONFIRMATION=required
|
|
96
|
+
|
|
97
|
+
# 寫入 Approval 專用 HMAC 金鑰,必須是 Base64 編碼的 32-byte 隨機值。
|
|
98
|
+
# 本機 stdio 可留空,由程序啟動時隨機生成;HTTP 或非本機部署必須配置並由 Secret Manager 管理。
|
|
99
|
+
# 產生方式:openssl rand -base64 32
|
|
100
|
+
PINGCODE_WRITE_APPROVAL_SECRET=replace-with-output-of-openssl-rand-base64-32
|
|
101
|
+
|
|
102
|
+
# Approval 與幂等紀錄有效期,單位秒。
|
|
103
|
+
PINGCODE_WRITE_APPROVAL_TTL_SECONDS=1800
|
|
104
|
+
PINGCODE_WRITE_IDEMPOTENCY_TTL_SECONDS=604800
|
|
105
|
+
|
|
106
|
+
# 寫入幂等狀態儲存。本機 UAT 可用 memory;非本機部署強制使用 redis。
|
|
107
|
+
PINGCODE_WRITE_STORE=memory
|
|
108
|
+
PINGCODE_WRITE_REDIS_URL=
|
|
109
|
+
|
|
110
|
+
# 日誌級別,可選 debug、info、warn、error。
|
|
111
|
+
LOG_LEVEL=info
|
|
112
|
+
|
|
113
|
+
# 選填:從另一個絕對路徑載入環境檔。
|
|
114
|
+
# 此變數應由啟動程序或 MCP Client 設定,不要寫在它指向的環境檔內。
|
|
115
|
+
# PINGCODE_ENV_FILE=/absolute/path/to/pingcode-mcp.env
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 本機 stdio 最小設定。
|
|
2
|
+
# 複製為 .env 後,只填 PingCode enterprise Client Credentials。
|
|
3
|
+
# stdio 不支援 user_oauth,也不需要 Redis、callback、公開 URL 或 OAuth Store。
|
|
4
|
+
|
|
5
|
+
PINGCODE_AUTH_MODE=enterprise
|
|
6
|
+
PINGCODE_CLIENT_ID=replace-with-enterprise-client-id
|
|
7
|
+
PINGCODE_CLIENT_SECRET=replace-with-enterprise-client-secret
|
|
8
|
+
|
|
9
|
+
# MCP 固定提供受控写入能力;只可搭配专用 UAT 凭据。stdio 用户在 MCP Client 中确认 Commit Tool,
|
|
10
|
+
# 不需要手动生成或粘贴 Approval Token,也不需要配置 Approval Secret。
|
|
11
|
+
# VS Code、ZCode 等客户端的工具审批弹窗由客户端控制,不由 MCP Server 或 .env 控制。
|
|
12
|
+
# 未配置时,stdio Server 每次启动会在内存中生成随机 Approval Secret,不写入磁盘或日志。
|
|
13
|
+
PINGCODE_WRITE_CONFIRMATION=required
|
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# PingCode MCP
|
|
2
|
+
|
|
3
|
+
讓 VS Code、Cursor、Qoder、ZCode 等 Coding Agent 安全連接 PingCode:讀取 Wiki、工作項目、Test Case 與測試庫上下文,並以 Preview → Approval → Commit 流程控管寫入與同步。適合 UAT 規劃、需求追蹤和測試資料維護,不提供任意 REST API 代理。
|
|
4
|
+
|
|
5
|
+
## 支援範圍
|
|
6
|
+
|
|
7
|
+
支援 Wiki、Task/工作項目、Test Case、測試庫、Project、Ship、Relation、使用者與成員角色的讀取,以及受控的 Task/Test Case、Project、Test Library、Ship、Relation、成員角色與需求模組寫入流程。寫入固定要求獨立權限、Preview、有效 Approval、幂等與稽核。
|
|
8
|
+
|
|
9
|
+
不支援 Wiki 寫入、Task/Project/Test Library/Idea 刪除或任意 PingCode REST API 代理;也不會主動刪除關係另一端資源。
|
|
10
|
+
|
|
11
|
+
## 快速安裝(推薦)
|
|
12
|
+
|
|
13
|
+
需要 Node.js 20 以上,以及在 PingCode 建立的 **enterprise 應用程式憑據**。npm 套件是 scoped package `@xurenxiang1219/pingcode-mcp`;請保留 scope,避免安裝到另一個同名套件。
|
|
14
|
+
|
|
15
|
+
### 1. 設定 PingCode 憑據
|
|
16
|
+
|
|
17
|
+
有兩種方式,選一種即可。
|
|
18
|
+
|
|
19
|
+
**推薦:使用私有環境檔**
|
|
20
|
+
|
|
21
|
+
將 `.env.stdio.local.example` 複製到只供本機使用的位置(例如 `/absolute/private/path/pingcode-mcp.env`),填入:
|
|
22
|
+
|
|
23
|
+
```env
|
|
24
|
+
PINGCODE_AUTH_MODE=enterprise
|
|
25
|
+
PINGCODE_CLIENT_ID=your-pingcode-client-id
|
|
26
|
+
PINGCODE_CLIENT_SECRET=your-pingcode-client-secret
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**懶人模式:直接放進 Client 的 `env`**
|
|
30
|
+
|
|
31
|
+
不想另外建立環境檔時,可以直接在 MCP 設定的 `env` 中加入:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
"env": {
|
|
35
|
+
"PINGCODE_AUTH_MODE": "enterprise",
|
|
36
|
+
"PINGCODE_CLIENT_ID": "your-pingcode-client-id",
|
|
37
|
+
"PINGCODE_CLIENT_SECRET": "your-pingcode-client-secret"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
這種方式最省事,但 Secret 會以明文保存在 Client 設定檔,只建議用於個人本機;不要提交、同步或分享該設定。stdio 模式會在程序記憶體中產生短效 Approval Secret,不需要手動產生或貼上 Approval Token。
|
|
42
|
+
|
|
43
|
+
### 2. 連接 MCP Client
|
|
44
|
+
|
|
45
|
+
#### VS Code
|
|
46
|
+
|
|
47
|
+
在終端機執行以下命令,將 Server 加入 VS Code 的 MCP 設定。請把環境檔路徑換成你的絕對路徑:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
code --add-mcp '{"name":"pingcode","command":"npx","args":["-y","@xurenxiang1219/pingcode-mcp","--stdio","--env-file","/absolute/private/path/pingcode-mcp.env"]}'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
不想建立環境檔時,也可以直接在命令中傳入憑據:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
code --add-mcp '{"name":"pingcode","command":"npx","args":["-y","@xurenxiang1219/pingcode-mcp","--stdio"],"env":{"PINGCODE_AUTH_MODE":"enterprise","PINGCODE_CLIENT_ID":"your-pingcode-client-id","PINGCODE_CLIENT_SECRET":"your-pingcode-client-secret"}}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
直接傳入的 Secret 會保存在 VS Code MCP 設定中,只建議用於個人本機;不要提交、同步或分享該設定。
|
|
60
|
+
|
|
61
|
+
也可以在工作區 `.vscode/mcp.json` 使用相同的 stdio Server;本 repository 已提供可直接使用的範例。
|
|
62
|
+
|
|
63
|
+
#### Cursor、Qoder、ZCode
|
|
64
|
+
|
|
65
|
+
這些 Client 使用 `mcpServers` 設定。將下列區塊放入各自的 MCP 設定檔(或在設定介面新增同等欄位),並替換環境檔的絕對路徑:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"pingcode": {
|
|
71
|
+
"command": "npx",
|
|
72
|
+
"args": [
|
|
73
|
+
"-y",
|
|
74
|
+
"@xurenxiang1219/pingcode-mcp",
|
|
75
|
+
"--stdio",
|
|
76
|
+
"--env-file",
|
|
77
|
+
"/absolute/private/path/pingcode-mcp.env"
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
不想建立環境檔時,使用下面的完整設定,直接填入 Client ID 與 Client Secret:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"pingcode": {
|
|
90
|
+
"command": "npx",
|
|
91
|
+
"args": ["-y", "@xurenxiang1219/pingcode-mcp", "--stdio"],
|
|
92
|
+
"env": {
|
|
93
|
+
"PINGCODE_AUTH_MODE": "enterprise",
|
|
94
|
+
"PINGCODE_CLIENT_ID": "your-pingcode-client-id",
|
|
95
|
+
"PINGCODE_CLIENT_SECRET": "your-pingcode-client-secret"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
如 Client 不支援 `--env-file` 參數,也可改用 `env` 傳入 `PINGCODE_ENV_FILE`,讓 Server 從私有環境檔讀取:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"pingcode": {
|
|
108
|
+
"command": "npx",
|
|
109
|
+
"args": ["-y", "@xurenxiang1219/pingcode-mcp", "--stdio"],
|
|
110
|
+
"env": {
|
|
111
|
+
"PINGCODE_ENV_FILE": "/absolute/private/path/pingcode-mcp.env"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 3. 啟動與首次寫入
|
|
119
|
+
|
|
120
|
+
啟動後先使用 Preview Tool 檢視變更,再由 Agent 呼叫對應的 Commit Tool。Server 會驗證 Preview hash、Approval Context、會話綁定、request hash、幂等鍵並記錄 `auditId`;是否顯示額外的 MCP Client 確認由 `PINGCODE_WRITE_CONFIRMATION` 控制(預設 `required`)。
|
|
121
|
+
|
|
122
|
+
stdio 本機模式不要求使用者手動生成 Approval Token;是否顯示額外確認由 `PINGCODE_WRITE_CONFIRMATION` 決定。
|
|
123
|
+
|
|
124
|
+
## 認證與環境變數
|
|
125
|
+
|
|
126
|
+
最小 stdio 設定只有以下三項:
|
|
127
|
+
|
|
128
|
+
| 變數 | 說明 |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| `PINGCODE_AUTH_MODE` | stdio 使用 `enterprise` |
|
|
131
|
+
| `PINGCODE_CLIENT_ID` | PingCode 應用程式 Client ID |
|
|
132
|
+
| `PINGCODE_CLIENT_SECRET` | PingCode 應用程式 Client Secret;建議放在私有環境檔或 Secret Manager,個人本機可直接設在 Client `env` |
|
|
133
|
+
|
|
134
|
+
程式也支援 `--env-file /path/to/file`、`--env-file=/path/to/file`,以及 `PINGCODE_ENV_FILE`。未指定時才會嘗試目前 package 目錄下的 `.env`。
|
|
135
|
+
|
|
136
|
+
## 進階:從原始碼執行
|
|
137
|
+
|
|
138
|
+
適合需要修改程式、執行測試或使用工作區 `.vscode/mcp.json` 的情境:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/xurenxiang1219/pingcode-mcp.git
|
|
142
|
+
cd pingcode-mcp
|
|
143
|
+
npm ci
|
|
144
|
+
cp .env.stdio.local.example .env
|
|
145
|
+
# 編輯 .env,填入 PINGCODE_CLIENT_ID 與 PINGCODE_CLIENT_SECRET
|
|
146
|
+
npm run build
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
完成後可在 VS Code 開啟此資料夾。`.vscode/mcp.json` 會以 `${workspaceFolder}/dist/index.js --stdio` 啟動 Server,並讀取同資料夾的 `.env`。
|
|
150
|
+
|
|
151
|
+
也可以直接啟動 npm 套件:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npx -y @xurenxiang1219/pingcode-mcp --stdio --env-file /absolute/private/path/pingcode-mcp.env
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
首次發佈由 package 維護者執行 `npm login` 後再執行 `npm publish --access public`;本 repository 不會在開發或測試時自動發佈。
|
|
158
|
+
|
|
159
|
+
## 工具
|
|
160
|
+
|
|
161
|
+
### 唯讀與上下文
|
|
162
|
+
|
|
163
|
+
- `pingcode_uat_runtime_info`
|
|
164
|
+
- `pingcode_wiki_list_spaces`
|
|
165
|
+
- `pingcode_wiki_list_pages`
|
|
166
|
+
- `pingcode_wiki_get_requirement_context`
|
|
167
|
+
- `pingcode_task_list`
|
|
168
|
+
- `pingcode_task_get`
|
|
169
|
+
- `pingcode_test_case_list`
|
|
170
|
+
- `pingcode_test_case_get`
|
|
171
|
+
- `pingcode_project_list`
|
|
172
|
+
- `pingcode_work_item_metadata_get`
|
|
173
|
+
- `pingcode_test_library_list`
|
|
174
|
+
- `pingcode_test_library_get`
|
|
175
|
+
- `pingcode_test_case_metadata_get`
|
|
176
|
+
- `pingcode_user_list`
|
|
177
|
+
- `pingcode_role_list`
|
|
178
|
+
- `pingcode_user_search`
|
|
179
|
+
- `pingcode_project_context_get`
|
|
180
|
+
- `pingcode_project_context_save`
|
|
181
|
+
- `pingcode_ship_product_list`
|
|
182
|
+
- `pingcode_ship_product_get`
|
|
183
|
+
- `pingcode_ship_idea_list`
|
|
184
|
+
- `pingcode_ship_product_idea_list`
|
|
185
|
+
- `pingcode_ship_idea_get`
|
|
186
|
+
- `pingcode_ship_product_suite_list`
|
|
187
|
+
- `pingcode_ship_product_suite_get`
|
|
188
|
+
- `pingcode_relation_list`
|
|
189
|
+
- `pingcode_relation_get`
|
|
190
|
+
- `pingcode_member_role_get`
|
|
191
|
+
|
|
192
|
+
### Preview、Commit 與受控寫入
|
|
193
|
+
|
|
194
|
+
- `pingcode_test_case_delete_preview` / `pingcode_test_case_delete_commit`
|
|
195
|
+
- `pingcode_test_case_bulk_create_preview` / `pingcode_test_case_bulk_create_commit`
|
|
196
|
+
- `pingcode_ship_product_sync_preview` / `pingcode_ship_product_sync_commit`
|
|
197
|
+
- `pingcode_ship_idea_sync_preview` / `pingcode_ship_idea_sync_commit`
|
|
198
|
+
- `pingcode_task_sync_preview` / `pingcode_task_sync_commit`
|
|
199
|
+
- `pingcode_test_case_sync_preview` / `pingcode_test_case_sync_commit`
|
|
200
|
+
- `pingcode_ship_product_suite_create_preview` / `pingcode_ship_product_suite_create_commit`
|
|
201
|
+
- `pingcode_ship_product_suite_remove_preview` / `pingcode_ship_product_suite_remove_commit`
|
|
202
|
+
- `pingcode_relation_sync_preview` / `pingcode_relation_sync_commit`
|
|
203
|
+
- `pingcode_member_role_update_preview` / `pingcode_member_role_update_commit`
|
|
204
|
+
- `pingcode_project_create_preview` / `pingcode_project_create_commit`
|
|
205
|
+
- `pingcode_test_library_create_preview` / `pingcode_test_library_create_commit`
|
|
206
|
+
|
|
207
|
+
## 安全機制與限制
|
|
208
|
+
|
|
209
|
+
- 唯讀與 Preview Tool 不修改 PingCode;所有 Commit Tool 都需要有效 Approval、不可變 request hash、Preview 證據、Approval Context、會話綁定和 idempotency key。
|
|
210
|
+
- PingCode 寫入請求不自動重試;結果不確定時,先用對應唯讀 Tool 回讀確認。
|
|
211
|
+
- Test Case 刪除必須先 Preview,再由獨立 Commit Tool 執行;完成後 MCP 會回讀確認用例不存在,並保留 Approval、hash、幂等鍵與稽核資料。
|
|
212
|
+
- 資源名稱、ID、成員與其他候選都必須來自 PingCode 目錄或使用者明確確認,不得猜測,也不得用空字串、`@` 或 `*` 作為通配符。
|
|
213
|
+
- 需要建立 `private` 專案或重用既有上下文時,Agent 必須先取得使用者確認;沒有確認的唯一候選也不能直接套用。
|
|
214
|
+
- Client ID、Client Secret、Token、Cookie 與客戶資料只應放在本機私有環境或 Secret Manager,不要提交、同步或分享。
|
|
215
|
+
|
|
216
|
+
## 本機開發驗證
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
npm run typecheck
|
|
220
|
+
npm test
|
|
221
|
+
npm run build
|
|
222
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve-write.d.ts","sourceRoot":"","sources":["../src/approve-write.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadConfig } from "./config.js";
|
|
3
|
+
import { loadEnvironment } from "./environment.js";
|
|
4
|
+
import { createApprovalToken, isWriteResourceType, writeResourceTypes } from "./write/approval.js";
|
|
5
|
+
loadEnvironment();
|
|
6
|
+
const resourceTypeList = writeResourceTypes.join("、");
|
|
7
|
+
const resourceTypeUsage = writeResourceTypes.join("|");
|
|
8
|
+
function main() {
|
|
9
|
+
const args = parseArgs(process.argv.slice(2));
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
if (!config.write.approvalSecret) {
|
|
12
|
+
throw new Error("尚未配置 PINGCODE_WRITE_APPROVAL_SECRET");
|
|
13
|
+
}
|
|
14
|
+
const resourceType = args.resource_type;
|
|
15
|
+
if (!isWriteResourceType(resourceType)) {
|
|
16
|
+
throw new Error(`--resource-type 必須是 ${resourceTypeList}`);
|
|
17
|
+
}
|
|
18
|
+
const requestHash = args.request_hash;
|
|
19
|
+
if (!requestHash || !/^sha256:[0-9a-f]{64}$/.test(requestHash)) {
|
|
20
|
+
throw new Error("--request-hash 必須是 Preview 返回的 sha256 hash");
|
|
21
|
+
}
|
|
22
|
+
const approvalContextId = args.approval_context_id;
|
|
23
|
+
if (!approvalContextId ||
|
|
24
|
+
!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(approvalContextId)) {
|
|
25
|
+
throw new Error("--approval-context-id 必須是 Preview 返回的 UUID");
|
|
26
|
+
}
|
|
27
|
+
const sessionBinding = requireHash(args.session_binding, "--session-binding");
|
|
28
|
+
const evidenceHash = requireHash(args.evidence_hash, "--evidence-hash");
|
|
29
|
+
const approvedBy = args.approved_by?.trim();
|
|
30
|
+
if (!approvedBy) {
|
|
31
|
+
throw new Error("必須提供 --approved-by");
|
|
32
|
+
}
|
|
33
|
+
const expiresAt = new Date(Date.now() + config.write.approvalTtlSeconds * 1000).toISOString();
|
|
34
|
+
const token = createApprovalToken({
|
|
35
|
+
version: 2,
|
|
36
|
+
approvalContextId,
|
|
37
|
+
sessionBinding,
|
|
38
|
+
evidenceHash,
|
|
39
|
+
requestHash,
|
|
40
|
+
resourceType: resourceType,
|
|
41
|
+
approvedBy,
|
|
42
|
+
expiresAt,
|
|
43
|
+
}, config.write.approvalSecret);
|
|
44
|
+
process.stdout.write(`${JSON.stringify({
|
|
45
|
+
approvalToken: token,
|
|
46
|
+
approvalContextId,
|
|
47
|
+
sessionBinding,
|
|
48
|
+
evidenceHash,
|
|
49
|
+
requestHash,
|
|
50
|
+
expiresAt,
|
|
51
|
+
}, null, 2)}\n`);
|
|
52
|
+
}
|
|
53
|
+
function requireHash(value, flag) {
|
|
54
|
+
if (!value || !/^sha256:[0-9a-f]{64}$/.test(value)) {
|
|
55
|
+
throw new Error(`${flag} 必須是 Preview 返回的 sha256 hash`);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
function parseArgs(values) {
|
|
60
|
+
const result = {};
|
|
61
|
+
for (let index = 0; index < values.length; index += 2) {
|
|
62
|
+
const flag = values[index];
|
|
63
|
+
const value = values[index + 1];
|
|
64
|
+
if (!flag?.startsWith("--") || value === undefined) {
|
|
65
|
+
throw new Error(`用法:npm run approve:write -- --resource-type <${resourceTypeUsage}> --request-hash <sha256:...> --approval-context-id <uuid> --session-binding <sha256:...> --evidence-hash <sha256:...> --approved-by <name>`);
|
|
66
|
+
}
|
|
67
|
+
result[flag.slice(2).replaceAll("-", "_")] = value;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
main();
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
process.stderr.write(`${JSON.stringify({
|
|
76
|
+
status: "error",
|
|
77
|
+
message: error instanceof Error ? error.message : "產生 Approval Token 失敗",
|
|
78
|
+
})}\n`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=approve-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve-write.js","sourceRoot":"","sources":["../src/approve-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { LookupAddress } from "node:dns";
|
|
2
|
+
import { type OAuthClientInformationFull } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
3
|
+
import type { Logger } from "../logger.js";
|
|
4
|
+
export interface CimdDocumentResponse {
|
|
5
|
+
status: number;
|
|
6
|
+
contentType: string | null;
|
|
7
|
+
cacheControl: string | null;
|
|
8
|
+
body: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CimdClientResolverLike {
|
|
11
|
+
resolve(clientId: string): Promise<OAuthClientInformationFull | undefined>;
|
|
12
|
+
}
|
|
13
|
+
interface CimdClientResolverOptions {
|
|
14
|
+
logger: Logger;
|
|
15
|
+
allowedHosts?: string[];
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
maxResponseBytes?: number;
|
|
18
|
+
lookup?: (hostname: string) => Promise<LookupAddress[]>;
|
|
19
|
+
requestDocument?: (url: URL, addresses: LookupAddress[], timeoutMs: number, maxResponseBytes: number) => Promise<CimdDocumentResponse>;
|
|
20
|
+
now?: () => number;
|
|
21
|
+
}
|
|
22
|
+
export declare class CimdClientResolver implements CimdClientResolverLike {
|
|
23
|
+
private readonly options;
|
|
24
|
+
private readonly cache;
|
|
25
|
+
private readonly allowedHosts;
|
|
26
|
+
private readonly timeoutMs;
|
|
27
|
+
private readonly maxResponseBytes;
|
|
28
|
+
private readonly lookup;
|
|
29
|
+
private readonly requestDocument;
|
|
30
|
+
private readonly now;
|
|
31
|
+
constructor(options: CimdClientResolverOptions);
|
|
32
|
+
resolve(clientId: string): Promise<OAuthClientInformationFull | undefined>;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=cimd-client-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cimd-client-resolver.d.ts","sourceRoot":"","sources":["../../src/auth/cimd-client-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAK9C,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAa3C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAC;CAC5E;AAED,UAAU,yBAAyB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACxD,eAAe,CAAC,EAAE,CAChB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,aAAa,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,KACrB,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAOD,qBAAa,kBAAmB,YAAW,sBAAsB;IASnD,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4D;IAC5F,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEN,OAAO,EAAE,yBAAyB;IAWzD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;CAwGjF"}
|