@zktx.io/sui-mcp 0.5.0 → 0.6.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.
Files changed (138) hide show
  1. package/README.md +21 -21
  2. package/dist/adapters/adapterPromptSurfaces.js +0 -20
  3. package/dist/adapters/deepbook/deepbookQuotePolicy.js +0 -4
  4. package/dist/adapters/deepbook/deepbookReviewEvidence.js +0 -9
  5. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +0 -9
  6. package/dist/adapters/intentPlanFactories.js +0 -6
  7. package/dist/core/action/contractNameRegistry.js +0 -53
  8. package/dist/core/action/forbiddenFields.js +0 -4
  9. package/dist/core/action/ptbVisualizationProducer.js +0 -3
  10. package/dist/core/action/receiptPtbGraph.js +0 -17
  11. package/dist/core/action/reviewTimeSimulationEvidence.js +0 -4
  12. package/dist/core/action/signableAdapterContract.js +0 -5
  13. package/dist/core/action/suiChainReceiptMapping.js +0 -18
  14. package/dist/core/action/suiChainReceiptReader.js +1 -21
  15. package/dist/core/action/suiChainReceiptVerifier.js +0 -10
  16. package/dist/core/action/transactionFunding.js +0 -7
  17. package/dist/core/action/types.js +0 -1
  18. package/dist/core/action/walletReviewContractAssembler.js +0 -2
  19. package/dist/core/activity/localDataService.js +65 -52
  20. package/dist/core/activity/localDataValidation.js +1 -3
  21. package/dist/core/activity/sqliteActivityStore.js +24 -24
  22. package/dist/core/activity/sqliteActivityStoreRows.js +0 -2
  23. package/dist/core/activity/sqliteActivityStoreSchema.js +81 -14
  24. package/dist/core/preferences/sqlitePreferencesRepository.js +5 -3
  25. package/dist/core/read/deepbookReadHelpers.js +0 -2
  26. package/dist/core/read/deepbookRegistry.js +0 -19
  27. package/dist/core/read/deepbookUsdcChartService.js +0 -2
  28. package/dist/core/read/readCardResult.js +0 -2
  29. package/dist/core/read/readService.js +0 -19
  30. package/dist/core/read/readServiceTypes.js +0 -2
  31. package/dist/core/session/cardSession.js +1 -5
  32. package/dist/core/session/cardSessionStore.js +54 -7
  33. package/dist/core/session/reviewValidity.js +0 -3
  34. package/dist/core/session/sessionRecordStore.js +0 -1
  35. package/dist/core/session/sessionStore.js +0 -32
  36. package/dist/core/session/settingsFileIdentity.js +9 -0
  37. package/dist/core/session/settingsFileProtocol.js +20 -0
  38. package/dist/core/session/settingsFileStore.js +337 -0
  39. package/dist/core/session/settingsInputError.js +32 -0
  40. package/dist/core/session/settingsOperation.js +220 -0
  41. package/dist/core/session/settingsPreparationSql.js +13 -0
  42. package/dist/core/session/settingsWorkflow.js +1183 -0
  43. package/dist/core/session/sqliteCardStore.js +0 -2
  44. package/dist/core/session/sqliteSessionStore.js +0 -51
  45. package/dist/core/session/sqliteSettingsWorkflowStore.js +453 -0
  46. package/dist/core/session/sqliteTransactionMaterialStore.js +0 -11
  47. package/dist/core/session/sqliteWalletWorkflowStore.js +160 -66
  48. package/dist/core/session/status.js +2 -4
  49. package/dist/core/session/transactionMaterialStore.js +0 -4
  50. package/dist/core/session/transactionRequest.js +0 -4
  51. package/dist/core/session/walletConnection.js +26 -10
  52. package/dist/core/session/walletWorkflow.js +70 -30
  53. package/dist/core/session/workflowState.js +14 -14
  54. package/dist/core/session/workflowView.js +18 -8
  55. package/dist/core/suiAddress.js +0 -5
  56. package/dist/core/suiEndpoint.js +0 -3
  57. package/dist/mcp/prompts.js +0 -12
  58. package/dist/mcp/responseGuidance.js +10 -5
  59. package/dist/mcp/schemas.js +0 -3
  60. package/dist/mcp/serverInfo.js +3 -4
  61. package/dist/mcp/toolNames.js +2 -2
  62. package/dist/mcp/tools/account/index.js +1 -19
  63. package/dist/mcp/tools/action/prepareSuiActionReview.js +0 -6
  64. package/dist/mcp/tools/read/readToolHelpers.js +5 -4
  65. package/dist/mcp/tools/read/serverStatusTools.js +0 -1
  66. package/dist/mcp/tools/session/executionResultTools.js +2 -2
  67. package/dist/mcp/tools/session/shared.js +1 -2
  68. package/dist/mcp/tools/session/statusTools.js +4 -5
  69. package/dist/mcp/tools/settings/index.js +8 -28
  70. package/dist/mcp-app/account.html +14 -14
  71. package/dist/mcp-app/account.notices.txt +1 -1
  72. package/dist/mcp-app/chart.html +9 -9
  73. package/dist/mcp-app/chart.notices.txt +1 -1
  74. package/dist/mcp-app/connect.html +14 -14
  75. package/dist/mcp-app/connect.notices.txt +1 -1
  76. package/dist/mcp-app/receipt.html +1298 -1463
  77. package/dist/mcp-app/receipt.notices.txt +226 -1204
  78. package/dist/mcp-app/review.html +1298 -1463
  79. package/dist/mcp-app/review.notices.txt +226 -1204
  80. package/dist/mcp-app/settings.html +3133 -0
  81. package/dist/mcp-app/settings.notices.txt +973 -0
  82. package/dist/mcp-ui/contracts.js +8 -2
  83. package/dist/mcp-ui/readCards.js +1 -1
  84. package/dist/mcp-ui/tools.js +34 -4
  85. package/dist/review-server/server.js +3 -51
  86. package/dist/runtime/application.js +41 -14
  87. package/dist/runtime/config.js +0 -2
  88. package/dist/runtime/localSettingsService.js +23 -2
  89. package/dist/runtime/logger.js +0 -2
  90. package/dist/runtime/reviewServerAcquire.js +1 -18
  91. package/dist/runtime/runtimeTermination.js +1 -4
  92. package/dist/runtime/shared/authenticatedFetch.js +2 -4
  93. package/dist/runtime/shared/control.js +4 -7
  94. package/dist/runtime/shared/dataAccess.js +0 -2
  95. package/dist/runtime/shared/http.js +14 -0
  96. package/dist/runtime/shared/mcpHttp.js +6 -6
  97. package/dist/runtime/shared/ownerLease.js +0 -4
  98. package/dist/runtime/shared/server.js +1 -2
  99. package/dist/runtime/shared/stdio.js +2 -5
  100. package/dist/runtime/smokeMainnetRead.js +0 -3
  101. package/dist/runtime/smokeReview.js +0 -4
  102. package/dist/runtime/start.js +0 -2
  103. package/dist/runtime/suiTransactionGraphqlMapping.js +0 -2
  104. package/dist/runtime/suiTransactionGraphqlQueries.js +0 -3
  105. package/dist/runtime/walletConnectConfig.js +0 -2
  106. package/dist/runtime/walletConnectStorage.js +2 -10
  107. package/dist/runtime/walletConnectTransport.js +0 -11
  108. package/dist/runtime/walletSdkChildRuntime.js +2 -6
  109. package/dist/runtime/walletSdkIpc.js +2 -1
  110. package/dist/runtime/walletSdkProcess.js +3 -8
  111. package/docs/AGENT_BEHAVIOR.md +45 -15
  112. package/docs/LOCAL_DB_ARCHITECTURE.md +145 -22
  113. package/docs/MCP_SETUP.md +99 -39
  114. package/docs/MCP_TOOLS.md +288 -24
  115. package/docs/SDK_API.md +63 -10
  116. package/docs/UTILITY_INDEX.md +9 -6
  117. package/docs/WALLET_CONNECTION.md +32 -10
  118. package/package.json +22 -8
  119. package/dist/core/activity/schemaVersion.js +0 -2
  120. package/dist/core/session/keyedRecordStore.js +0 -18
  121. package/dist/core/session/settingsSession.js +0 -1
  122. package/dist/core/session/settingsSessions.js +0 -45
  123. package/dist/review-app/brand-dark.svg +0 -1
  124. package/dist/review-app/brand-light.svg +0 -1
  125. package/dist/review-app/favicon.svg +0 -1
  126. package/dist/review-app/settings.css +0 -1
  127. package/dist/review-app/settings.js +0 -1
  128. package/dist/review-app/ui.css +0 -809
  129. package/dist/review-server/assets.js +0 -48
  130. package/dist/review-server/html.js +0 -45
  131. package/dist/review-server/http.js +0 -47
  132. package/dist/review-server/middleware/reviewToken.js +0 -7
  133. package/dist/review-server/settingsApi.js +0 -158
  134. package/docs/AGENT_DEVELOPMENT_POLICY.md +0 -815
  135. package/docs/FRONTEND_POLICY.md +0 -534
  136. package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +0 -166
  137. package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +0 -161
  138. package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +0 -259
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zktx.io/sui-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "mcpName": "io.github.zktx-mcp/sui-mcp",
5
5
  "description": "Sui MCP is a local-first toolkit for helping AI applications and users inspect Sui DeFi actions before execution.",
6
6
  "license": "MIT",
@@ -11,7 +11,15 @@
11
11
  "files": [
12
12
  "dist/",
13
13
  "README.md",
14
- "docs/",
14
+ "docs/MCP_SETUP.md",
15
+ "docs/MCP_TOOLS.md",
16
+ "docs/AGENT_BEHAVIOR.md",
17
+ "docs/WALLET_CONNECTION.md",
18
+ "docs/LOCAL_DB_ARCHITECTURE.md",
19
+ "docs/SDK_API.md",
20
+ "docs/SIGNABLE_ADAPTER_CONTRACT.md",
21
+ "docs/TRANSACTION_ACTIVITY_LOG.md",
22
+ "docs/UTILITY_INDEX.md",
15
23
  "protocols/deepbook-v3.md",
16
24
  "protocols/deepbook-margin.md",
17
25
  "LICENSE",
@@ -39,7 +47,7 @@
39
47
  },
40
48
  "scripts": {
41
49
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
42
- "build": "npm run clean && tsc -p tsconfig.build.json && vite build && tsx scripts/build-mcp-ui.ts",
50
+ "build": "npm run clean && tsc -p tsconfig.build.json && tsx scripts/build-mcp-ui.ts",
43
51
  "prepublishOnly": "npm run release:check",
44
52
  "release:check": "tsx scripts/release-check.ts",
45
53
  "smoke:mainnet": "node dist/runtime/smokeMainnetRead.js",
@@ -49,9 +57,10 @@
49
57
  },
50
58
  "dependencies": {
51
59
  "@modelcontextprotocol/ext-apps": "1.7.5",
52
- "@modelcontextprotocol/sdk": "1.29.0",
60
+ "@modelcontextprotocol/sdk": "1.31.0",
53
61
  "@mysten/deepbook-v3": "1.3.6",
54
62
  "@mysten/sui": "2.17.0",
63
+ "@noble/hashes": "2.2.0",
55
64
  "@scure/bip39": "2.2.0",
56
65
  "@walletconnect/sign-client": "2.23.10",
57
66
  "@walletconnect/types": "2.23.10",
@@ -59,19 +68,24 @@
59
68
  "@zktx.io/ptb-model": "0.5.0",
60
69
  "better-sqlite3": "12.9.0",
61
70
  "lightweight-charts": "5.2.0",
62
- "mermaid": "11.12.0",
63
71
  "qrcode": "1.5.4",
64
72
  "zod": "4.4.3"
65
73
  },
74
+ "overrides": {
75
+ "mermaid@11.16.1": {
76
+ "katex": "0.18.2"
77
+ }
78
+ },
66
79
  "devDependencies": {
67
80
  "@types/better-sqlite3": "7.6.13",
68
81
  "@types/node": "25.6.2",
69
82
  "@types/qrcode": "1.5.6",
70
83
  "marked": "16.4.2",
71
- "tsx": "4.21.0",
84
+ "mermaid": "11.16.1",
85
+ "tsx": "4.22.0",
72
86
  "typescript": "6.0.3",
73
- "vite": "8.0.11",
74
- "vitest": "4.1.5"
87
+ "vite": "8.0.16",
88
+ "vitest": "4.1.11"
75
89
  },
76
90
  "engines": {
77
91
  "node": ">=22"
@@ -1,2 +0,0 @@
1
- // Current-format-only storage; existing databases are never migrated.
2
- export const DB_USER_VERSION = 9;
@@ -1,18 +0,0 @@
1
- export class InMemoryKeyedRecordStore {
2
- records = new Map();
3
- get(id) {
4
- return this.records.get(id);
5
- }
6
- set(id, value) {
7
- this.records.set(id, value);
8
- }
9
- delete(id) {
10
- this.records.delete(id);
11
- }
12
- ids() {
13
- return [...this.records.keys()];
14
- }
15
- clear() {
16
- this.records.clear();
17
- }
18
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,45 +0,0 @@
1
- import { cloneLocalSession, createLocalSessionBase, isLocalSessionExpired, tokenMatchesHash } from "./localSession.js";
2
- import { InMemoryKeyedRecordStore } from "./keyedRecordStore.js";
3
- export class SettingsSessionManager {
4
- options;
5
- sessions;
6
- constructor(options) {
7
- this.options = options;
8
- this.sessions = options.recordStore ?? new InMemoryKeyedRecordStore();
9
- }
10
- async create(now) {
11
- const { base, token } = createLocalSessionBase(now, this.options.ttlMs);
12
- const session = {
13
- ...base,
14
- type: "local_settings"
15
- };
16
- this.sessions.set(session.id, session);
17
- await this.options.appendEventLog({
18
- type: "settings_session.created",
19
- sessionId: session.id,
20
- at: now.toISOString()
21
- });
22
- return { session: cloneLocalSession(session), token };
23
- }
24
- async get(id, now) {
25
- const session = this.sessions.get(id);
26
- if (!session) {
27
- return undefined;
28
- }
29
- if (isLocalSessionExpired(session, now)) {
30
- this.sessions.delete(id);
31
- return undefined;
32
- }
33
- return cloneLocalSession(session);
34
- }
35
- async validateToken(id, token, now) {
36
- const session = await this.get(id, now);
37
- if (!session) {
38
- return false;
39
- }
40
- return tokenMatchesHash(session.tokenHash, token);
41
- }
42
- clear() {
43
- this.sessions.clear();
44
- }
45
- }
@@ -1 +0,0 @@
1
- <svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Sui MCP mark"><g transform="translate(50.000 56.944) scale(1.1031)" fill="#4DA2FF"><g transform="rotate(0)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(120)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(240)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g></g></svg>
@@ -1 +0,0 @@
1
- <svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Sui MCP mark"><g transform="translate(50.000 56.944) scale(1.1031)" fill="#1565C0"><g transform="rotate(0)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(120)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(240)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g></g></svg>
@@ -1 +0,0 @@
1
- <svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Sui MCP mark"><g transform="translate(50.000 56.944) scale(1.1031)" fill="#1565C0"><g transform="rotate(0)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(120)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g><g transform="rotate(240)"><path d="M0 -46 C11 -40 23 -32 23 -25 C23 -18 11 -10 0 -4 C-11 -10 -23 -18 -23 -25 C-23 -32 -11 -40 0 -46 Z"/></g></g></svg>
@@ -1 +0,0 @@
1
- .settings-title{margin:8px 0 6px;font-size:22px;line-height:1.2}.settings-file{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}
@@ -1 +0,0 @@
1
- function e(e,t,n){let r=document.createElement(e);return t&&(r.className=t),n!==void 0&&(r.textContent=n),r}function t(e,t,n=`primary`){let r=document.createElement(`button`);return r.type=`button`,r.className=n===`primary`?`ui-btn ui-btn--primary`:n===`danger`?`ui-btn ui-btn--danger`:`ui-btn`,r.textContent=e,r.addEventListener(`click`,t),r}function n(e,t,n){let r=document.createElement(`button`);return r.type=`button`,r.className=`ui-icon-btn`,r.setAttribute(`aria-label`,t),r.innerHTML=e,r.addEventListener(`click`,n),r}function r(...t){let n=e(`div`,`ui-btn-row`);return n.append(...t),n}function i(e){let t=r(e);return t.classList.add(`ui-btn-row--end`),t}function a(e){let t=document.createElement(`input`);return t.className=`ui-input`,t.type=e.type??`text`,e.value!==void 0&&(t.value=e.value),e.placeholder!==void 0&&(t.placeholder=e.placeholder),e.id&&(t.id=e.id),e.name&&(t.name=e.name),t.autocomplete=`off`,t}function o(t){let n=e(`section`,`ui-card`);return t&&n.append(e(`h2`,`ui-card-head`,t)),n}function s(t,n){let r=e(`div`,`ui-row`);r.append(e(`span`,`ui-row-label`,t));let i=e(`span`,`ui-row-value`);return typeof n==`string`?i.textContent=n:i.append(n),r.append(i),r}function c(t,n,r){let i=e(`div`,t===`error`?`ui-feedback ui-feedback--error`:`ui-feedback ui-feedback--ok`);return i.setAttribute(`role`,`status`),i.setAttribute(`aria-live`,`polite`),i.append(e(`span`,void 0,n)),r&&i.append(e(`span`,`ui-feedback-detail`,r)),i}function l(t){return e(`p`,`ui-note`,t)}var u=`sui-mcp-theme`;function d(){try{let e=localStorage.getItem(u);return e===`light`||e===`dark`?e:void 0}catch{return}}function f(e){try{localStorage.setItem(u,e)}catch{}}function p(){try{return window.matchMedia(`(prefers-color-scheme: dark)`).matches}catch{return!1}}function m(){return document.documentElement.getAttribute(`data-theme`)===`dark`?`dark`:`light`}function h(e){document.documentElement.setAttribute(`data-theme`,e)}function g(){let e=d()??(p()?`dark`:`light`);return h(e),e}function _(e){h(e),f(e)}function v(){let e=m()===`dark`?`light`:`dark`;return _(e),e}var y={brand:`Sui MCP`,shell:{toggleTheme:`Toggle theme`},account:{name:`Name`,address:`Account address`,balances:`Balances`,noBalances:`No token balances were returned.`,nfts:`NFTs`,noNfts:`No NFTs in the scanned objects.`,noImage:`No image`,objectsTruncated:`Some objects beyond the scanned range are omitted.`},receipt:{success:`Transaction succeeded on Sui`,failure:`Transaction failed on Sui`,sender:`Sender`,account:`Affected account`,object:`Object`,noBalanceChanges:`No balance changes were recorded.`,gasComputation:`Computation cost`,gasStorage:`Storage cost`,gasRebate:`Storage rebate`,gasBudget:`Network fee limit (gas budget)`,netFeeExplanation:`The network fee shown above includes the storage rebate. If it is negative, the rebate exceeds the computation and storage charges.`,estimatedNetFeeExplanation:`The estimated network fee shown above includes the storage rebate. If it is negative, the rebate exceeds the estimated computation and storage charges.`,gasLimitExplanation:`The gas budget limits network fee spending. It is not an estimate of the amount charged.`,gasPrice:`Gas price`,gasPayment:`Gas payment object`,graph:`Transaction graph`,graphTip:`A diagram of this transaction's programmable transaction block (PTB), derived from public on-chain data. It is a diagnostic view only, not transaction input, signing, or a safety verdict.`,graphReviewTip:`A diagram of the transaction prepared for this review and simulation. It shows what is being reviewed, not an actual result, permission to sign, or a guarantee of safety.`,graphRendering:`Rendering the transaction graph…`,graphFailed:`The transaction graph could not be rendered`,graphZoomIn:`Zoom in`,graphZoomOut:`Zoom out`,graphCenter:`Center`,graphShowAddresses:`Show full addresses`,graphShowNames:`Show readable labels`,moveCalls:`Move calls`,noMoveCalls:`No Move calls were recorded.`,inputs:`Inputs`,noInputs:`No inputs were recorded.`,inputKinds:{object:`Owned object`,shared_object:`Shared object`,receiving:`Receiving object`,pure:`Pure value`,withdrawal:`Balance withdrawal`,unknown:`Input`},bytes:`bytes`,events:`Events`,noEvents:`No events were recorded.`,objectChanges:`Object changes`,noObjectChanges:`No object changes were recorded.`},chart:{boundaryUsdc:`Prices are in USDC, not USD; dollar parity is not guaranteed.`,boundaryScope:`Historical prices, not live quotes.`,source:`Source: DeepBookV3 Indexer.`,renderedWith:`Rendered with`,library:`TradingView Lightweight Charts`},common:{walletStatusRecovery:`To restart the connection service, fully quit all apps using Sui MCP, then reopen them. This does not confirm removal of a connection in your wallet app.`,mainnet:`Sui mainnet`,retrievedAt:`Data retrieved`}},b={en:y};function ee(){try{return(navigator.language||`en`).slice(0,2).toLowerCase()}catch{return`en`}}function te(e=ee()){return b[e]??y}var x=te(),S=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>`,ne=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>`;function C(e){return e===`dark`?ne:S}function w(e){let t=document.createElement(`img`);return t.className=e,t.src=`/review-assets/${e===`ui-brand-light`?`brand-light`:`brand-dark`}.svg`,t.alt=``,t.width=24,t.height=24,t}function T(){let t=e(`span`,`ui-brand`);return t.append(w(`ui-brand-light`),w(`ui-brand-dark`),e(`span`,void 0,x.brand)),t}function E(t){g();let r=e(`div`,`ui-shell`),i=e(`header`,`ui-header`);i.append(T()),i.append(e(`span`,`ui-header-spacer`));let a=n(C(m()),x.shell.toggleTheme,()=>{a.innerHTML=C(v())});i.append(a);let o=e(`main`,`ui-main`),s=e(`div`,`ui-overlay`);s.setAttribute(`role`,`status`),s.setAttribute(`aria-live`,`polite`);let c=e(`div`,`ui-overlay-box`);c.append(e(`div`,`ui-spinner`));let l=e(`span`,`ui-overlay-label`,`Processing…`);return c.append(l),s.append(c),r.append(i),r.append(o,s),t.replaceChildren(r),{root:r,main:o,setBusy(e,t){t&&(l.textContent=t),e?r.setAttribute(`aria-busy`,`true`):r.removeAttribute(`aria-busy`)}}}var D=class extends Error{constructor(e,t){super(`HTTP JSON request failed: ${e} ${t}`),this.status=e,this.code=t}};async function O(e){try{let t=await e.json();if(typeof t.error==`string`&&t.error.length>0)return t.error}catch{}return`http_${e.status}`}function k(e,t){return e instanceof D?e.code===`wallet_request_unsettled`?`A wallet request is still being settled. Local data cannot be replaced yet.`:`${t} (${e.code})`:t}var A=`x-sui-mcp-token`;function j(){let e=window.location.hash;return e.startsWith(`#`)?e.slice(1):``}function re(e,t){return{...t,[A]:e}}var M=16*1024*1024,N=document.querySelector(`#settings-app`);if(!N)throw Error(`settings app root missing`);var P=N,F=P.dataset.settingsSessionId??``,I=j(),L=E(P).main,R,z,B,V,H,U;function W(e,n,r=`primary`){let i=t(e,n,r);return i.disabled=H!==void 0,i}function G(e){if(H?.scope===e)return l(H.text);if(U?.scope===e)return c(U.kind,U.text)}function K(e,t){let n=G(t);n&&e.append(n)}F&&I?X():q();function q(){let t=[];if(t.push(e(`h1`,`settings-title`,`Sui MCP Settings`)),t.push(l(`Use this local page to manage the default address for reads, local data, and Sui read endpoints. Settings changes do not sign transactions or grant custody.`)),V&&t.push(c(`error`,V)),!F||!I){t.push(c(`error`,`Missing settings session id or token. Open the settings URL from your AI client again.`)),L.replaceChildren(...t);return}t.push(J(),Y(),ie(),ae(),oe()),L.replaceChildren(...t)}function J(){let e=o(`Status`);return R?(e.append(s(`Server`,`${R.server.name} ${R.server.version}`)),e.append(s(`Network`,R.server.network)),e.append(s(`Endpoint source`,R.localSettings.suiGrpcUrl.source)),e.append(s(`Effective endpoint`,R.localSettings.suiGrpcUrl.effectiveValue)),e.append(s(`Stored endpoint`,R.localSettings.suiGrpcUrl.storedValue)),e.append(s(`GraphQL endpoint source`,R.localSettings.suiGraphqlUrl.source)),e.append(s(`Effective GraphQL endpoint`,R.localSettings.suiGraphqlUrl.effectiveValue)),e.append(s(`Stored GraphQL endpoint`,R.localSettings.suiGraphqlUrl.storedValue)),e.append(s(`Restart required`,R.restartRequired?`yes`:`no`)),e.append(s(`Default address`,R.activeAccount?.account??`none`)),e.append(s(`Data counts`,Object.entries(R.dataCounts).map(([e,t])=>`${e}: ${t}`).join(`, `))),e):(e.append(l(`Loading…`)),e)}function Y(){let e=o(`Default address for reads`);return e.append(l(`Clearing the default address does not disconnect your wallet or revoke onchain permission. Choose an approved address or disconnect in the wallet connection card.`)),R?.activeAccount?e.append(i(W(`Clear default address`,()=>void se(),`secondary`))):e.append(l(R?`No default address is selected.`:`Loading…`)),K(e,`wallet`),e}function ie(){let t=o(`Sui gRPC endpoint`),n=a({type:`url`,value:R?.localSettings.suiGrpcUrl.storedValue??``,placeholder:`https://fullnode.mainnet.sui.io:443`});n.maxLength=512,n.setAttribute(`aria-label`,`Sui gRPC endpoint URL`),t.append(n),t.append(r(W(`Save endpoint`,()=>void ce(n.value)),W(`Restore default Sui gRPC URL`,()=>void le(),`secondary`))),K(t,`grpc`);let i=o(`Sui GraphQL endpoint`),s=a({type:`url`,value:R?.localSettings.suiGraphqlUrl.storedValue??``,placeholder:`https://graphql.mainnet.sui.io/graphql`});s.maxLength=512,s.setAttribute(`aria-label`,`Sui GraphQL endpoint URL`),i.append(s),i.append(r(W(`Save GraphQL endpoint`,()=>void ue(s.value)),W(`Restore default Sui GraphQL URL`,()=>void de(),`secondary`))),K(i,`graphql`);let c=e(`div`,`settings-endpoints`);return c.append(t,i),c}function ae(){let e=o(`Local data`);e.append(l(`Export downloads a backup of your local data. Import previews a chosen backup file (shape only); endpoint verification runs when you confirm, and importing replaces current local data and invalidates open cards and settings sessions.`));let t=document.createElement(`input`);return t.type=`file`,t.accept=`application/json,.json`,t.className=`settings-file`,t.setAttribute(`aria-label`,`Choose a Sui MCP backup file to import`),t.onchange=()=>void pe(t),e.append(r(W(`Export local data`,()=>void fe()),W(`Choose backup file…`,()=>t.click(),`secondary`))),e.append(t),B&&(e.append(c(`ok`,`Import preview ready. Incoming accounts: ${B.incomingCounts.accounts}. Active account change: ${B.activeAccountChange}. Endpoint verification runs before replacement. This import replaces current local data.`)),e.append(l($())),e.append(i(W(`Import and replace local data`,()=>void me(),`danger`)))),K(e,`localData`),e}function oe(){let e=o(`Danger zone`);return e.append(l(`Reset permanently clears all local Sui MCP data and invalidates every open card and settings session. This cannot be undone.`)),e.append(l($())),e.append(i(W(`Reset local data`,()=>void he(),`danger`))),K(e,`danger`),e}async function X(){try{R=await Q(`/api/settings/${encodeURIComponent(F)}`,{method:`GET`}),V=void 0}catch(e){V=k(e,`The local server did not accept this settings session.`)}q()}async function se(){window.confirm(`Clear the default address for reads? This does not disconnect your wallet or revoke onchain permission.`)&&await Z(`wallet`,`clear-active-account`,`Default address cleared.`)}async function ce(e){if(e.length>512){U={scope:`grpc`,kind:`error`,text:`Sui gRPC endpoint must be 512 characters or fewer.`},q();return}await Z(`grpc`,`sui-grpc-url`,`Sui gRPC endpoint saved. Restart the MCP server for the stored value to apply.`,{url:e},`Verifying and saving the Sui gRPC endpoint...`)}async function le(){window.confirm(`Restore the built-in default Sui gRPC URL? Restart the MCP server for the restored value to apply.`)&&await Z(`grpc`,`sui-grpc-url/restore-default`,`Default Sui gRPC URL restored. Restart the MCP server for it to apply.`)}async function ue(e){if(e.length>512){U={scope:`graphql`,kind:`error`,text:`Sui GraphQL endpoint must be 512 characters or fewer.`},q();return}await Z(`graphql`,`sui-graphql-url`,`Sui GraphQL endpoint saved. Restart the MCP server for the stored value to apply.`,{url:e},`Verifying and saving the Sui GraphQL endpoint...`)}async function de(){window.confirm(`Restore the built-in default Sui GraphQL URL? Restart the MCP server for the restored value to apply.`)&&await Z(`graphql`,`sui-graphql-url/restore-default`,`Default Sui GraphQL URL restored. Restart the MCP server for it to apply.`)}async function fe(){try{H={scope:`localData`,text:`Preparing local data export...`},U=void 0,q();let e=await Q(`/api/settings/${encodeURIComponent(F)}/local-data/export`,{method:`GET`}),t=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),n=document.createElement(`a`),r=URL.createObjectURL(t);n.href=r,n.download=`sui-mcp-local-data-${new Date().toISOString().replaceAll(`:`,`-`)}.json`,n.click(),window.setTimeout(()=>URL.revokeObjectURL(r),0),H=void 0,U={scope:`localData`,kind:`ok`,text:`Local data export prepared.`}}catch(e){H=void 0,U={scope:`localData`,kind:`error`,text:k(e,`Could not export local data.`)}}q()}async function pe(e){let t=e.files?.[0];if(t){if(t.size>M){z=void 0,B=void 0,U={scope:`localData`,kind:`error`,text:`Import file is too large. Maximum size is ${ge(M)}.`},e.value=``,q();return}try{H={scope:`localData`,text:`Loading import preview...`},U=void 0,q(),z=JSON.parse(await t.text()),B=await Q(`/api/settings/${encodeURIComponent(F)}/local-data/import/preview`,{method:`POST`,body:JSON.stringify(z)}),H=void 0,U={scope:`localData`,kind:`ok`,text:`Import preview loaded. Endpoint verification will run only if you confirm import.`}}catch(t){z=void 0,B=void 0,e.value=``,H=void 0,U={scope:`localData`,kind:`error`,text:k(t,`Import preview failed. Check that the file is a Sui MCP local data export.`)}}q()}}async function me(){if(z&&window.confirm(`Import and replace all local data? This invalidates all open cards and settings sessions. `+$())){try{H={scope:`localData`,text:`Importing local data...`},U=void 0,q(),await Q(`/api/settings/${encodeURIComponent(F)}/local-data/import`,{method:`POST`,body:JSON.stringify(z)}),H=void 0,U={scope:`localData`,kind:`ok`,text:`Local data imported. This settings page is now invalid; create a new settings session to continue.`},z=void 0,B=void 0}catch(e){H=void 0,U={scope:`localData`,kind:`error`,text:k(e,`Could not import local data.`)}}q()}}async function he(){if(window.confirm(`Reset all local Sui MCP data? This invalidates all open cards and settings sessions. `+$())){try{H={scope:`danger`,text:`Resetting local data...`},U=void 0,q(),await Q(`/api/settings/${encodeURIComponent(F)}/local-data/reset`,{method:`POST`,body:`{}`}),H=void 0,U={scope:`danger`,kind:`ok`,text:`Local data reset. This settings page is now invalid; create a new settings session to continue.`}}catch(e){H=void 0,U={scope:`danger`,kind:`error`,text:k(e,`Could not reset local data.`)}}q()}}async function Z(e,t,n,r={},i=`Sending local settings request...`){H={scope:e,text:i},U=void 0,q();try{await Q(`/api/settings/${encodeURIComponent(F)}/${t}`,{method:`POST`,body:JSON.stringify(r)}),H=void 0,U={scope:e,kind:`ok`,text:n},await X()}catch(t){H=void 0,U={scope:e,kind:`error`,text:k(t,`The local settings request failed.`)},q()}}async function Q(e,t){let n=t.body===void 0?void 0:{"content-type":`application/json`},r=await fetch(e,{...t,headers:re(I,n)});if(!r.ok)throw new D(r.status,await O(r));return await r.json()}function ge(e){let t=e/(1024*1024);return Number.isInteger(t)?`${t} MiB`:`${e} bytes`}function $(){return`Replacement removes stored requests, including any with an unconfirmed chain outcome. Removing local records cannot cancel or reverse a transaction on Sui. Export the records before replacement if you need to investigate them later.`}