codebase-onboarder 0.5.0 → 0.7.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/README.md +196 -47
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +449 -0
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +396 -229
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +400 -162
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +73 -0
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +173 -0
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +184 -95
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +496 -412
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +33 -0
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +235 -138
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +55 -35
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +165 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +60 -0
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -37
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +79 -0
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
|
@@ -6,184 +6,173 @@
|
|
|
6
6
|
// app.js is the drawer choreography — one scrim at a time, Escape to close —
|
|
7
7
|
// which is why it returns open/close/isOpen instead of wiring the topbar
|
|
8
8
|
// button itself.
|
|
9
|
-
|
|
10
9
|
import { fetchServerSettings, updateServerSettings, rotateServerAccessKey, logoutRemoteSession } from '/js/api.js';
|
|
11
|
-
|
|
12
10
|
// A function declaration, not a const arrow: the import-time DOM check in
|
|
13
11
|
// tests/frontend.test.js blanks top-level function bodies but reads const
|
|
14
12
|
// bodies, and this module must stay importable from Node.
|
|
15
13
|
function $(id) {
|
|
16
|
-
|
|
14
|
+
return document.getElementById(id);
|
|
17
15
|
}
|
|
18
|
-
|
|
19
16
|
const MODE_NOTES = {
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
local: 'Local mode answers only this machine. No key, no network — the safe default.',
|
|
18
|
+
'self-hosted': 'Self-hosted answers whoever can reach the port, so every API call needs the access key below.',
|
|
22
19
|
};
|
|
23
|
-
|
|
24
20
|
export function createServerDrawer(options = {}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
dom.srvStatus.className = 'drawer-status' + (cls ? ' ' + cls : '');
|
|
42
|
-
dom.srvStatus.textContent = text;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function tunnelLine(el, t) {
|
|
46
|
-
if (!t) { el.textContent = ''; return; }
|
|
47
|
-
if (!t.enabled) {
|
|
48
|
-
el.textContent = t.installed ? 'Off.' : `Off — and ${t.install || 'the binary is not installed'}.`;
|
|
49
|
-
return;
|
|
21
|
+
// Pulled out of the parameter list on purpose: the front-end static check
|
|
22
|
+
// in tests/frontend.test.js only understands plain params, and `toast` must
|
|
23
|
+
// show up as a declaration, not a dangling call.
|
|
24
|
+
const toast = typeof options.toast === 'function' ? options.toast : (..._args) => { };
|
|
25
|
+
const dom = {};
|
|
26
|
+
[
|
|
27
|
+
'serverDrawer', 'serverScrim', 'serverClose', 'serverModeNote', 'srvMode', 'srvHost', 'srvPort',
|
|
28
|
+
'srvDomain', 'srvDomainField', 'srvHttps', 'srvHttpsField', 'srvHttpsStatus', 'srvAutoOpen', 'srvKeySection', 'srvKeyMasked', 'srvRotate', 'srvLogout',
|
|
29
|
+
'srvFreshKeyRow', 'srvFreshKey', 'srvCopyKey', 'srvKeyHint', 'srvName', 'srvEmail',
|
|
30
|
+
'srvTunnelCloudflare', 'srvTunnelCloudflareStatus', 'srvTunnelTailscale', 'srvTunnelTailscaleStatus',
|
|
31
|
+
'srvSave', 'srvStatus', 'srvConfigPath',
|
|
32
|
+
].forEach((id) => (dom[id] = $(id)));
|
|
33
|
+
let current = null; // the last settings body the server sent
|
|
34
|
+
function status(text, cls = '') {
|
|
35
|
+
dom.srvStatus.className = 'drawer-status' + (cls ? ' ' + cls : '');
|
|
36
|
+
dom.srvStatus.textContent = text;
|
|
50
37
|
}
|
|
51
|
-
el
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
dom.srvDomain.value = s.domain || '';
|
|
64
|
-
dom.srvHttps.checked = Boolean(s.https);
|
|
65
|
-
dom.srvHttpsStatus.textContent = data.https?.caddyInstalled
|
|
66
|
-
? `Caddy ${data.https.caddyVersion || 'installed'}. ${s.https ? 'Run `onboarder https setup` after saving.' : 'Enable HTTPS above, save, then run the command.'}`
|
|
67
|
-
: 'Caddy is not installed. Ubuntu: sudo apt install caddy; macOS: brew install caddy.';
|
|
68
|
-
dom.srvAutoOpen.checked = Boolean(s.autoOpen);
|
|
69
|
-
dom.srvName.value = s.account?.name || '';
|
|
70
|
-
dom.srvEmail.value = s.account?.email || '';
|
|
71
|
-
dom.srvTunnelCloudflare.checked = Boolean(s.tunnel?.cloudflare);
|
|
72
|
-
dom.srvTunnelTailscale.checked = Boolean(s.tunnel?.tailscale);
|
|
73
|
-
tunnelLine(dom.srvTunnelCloudflareStatus, data.tunnels?.cloudflare);
|
|
74
|
-
tunnelLine(dom.srvTunnelTailscaleStatus, data.tunnels?.tailscale);
|
|
75
|
-
dom.srvConfigPath.textContent = `Config file: ${data.configFile}`;
|
|
76
|
-
dom.srvKeyMasked.value = s.accessKeyMasked || (s.hasAccessKey ? '' : '(none set — the API refuses every call)');
|
|
77
|
-
dom.srvKeyHint.textContent = s.hasAccessKey
|
|
78
|
-
? 'Remote browsers sign in once; the key is exchanged for a secure HTTP-only session.'
|
|
79
|
-
: 'No key is set. Generate one before remote access is possible.';
|
|
80
|
-
applyModeVisibility();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Mode drives which rows even make sense: local wipes the network/security
|
|
84
|
-
// fields in the schema, so asking for them here would be collecting lies.
|
|
85
|
-
function applyModeVisibility() {
|
|
86
|
-
const remote = dom.srvMode.value === 'self-hosted';
|
|
87
|
-
dom.srvKeySection.hidden = !remote;
|
|
88
|
-
dom.srvDomainField.hidden = !remote;
|
|
89
|
-
dom.srvHttpsField.hidden = !remote || !dom.srvDomain.value.trim();
|
|
90
|
-
dom.serverModeNote.textContent = MODE_NOTES[dom.srvMode.value] || '';
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function open() {
|
|
94
|
-
dom.serverDrawer.hidden = false;
|
|
95
|
-
dom.serverScrim.hidden = false;
|
|
96
|
-
dom.srvFreshKeyRow.hidden = true;
|
|
97
|
-
status('Reading the server…');
|
|
98
|
-
try {
|
|
99
|
-
render(await fetchServerSettings());
|
|
100
|
-
status('');
|
|
101
|
-
} catch (err) {
|
|
102
|
-
status(err.message, 'err');
|
|
38
|
+
function tunnelLine(el, t) {
|
|
39
|
+
if (!t) {
|
|
40
|
+
el.textContent = '';
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!t.enabled) {
|
|
44
|
+
el.textContent = t.installed ? 'Off.' : `Off — and ${t.install || 'the binary is not installed'}.`;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
el.textContent = t.installed
|
|
48
|
+
? `On. Start it with: ${t.command}`
|
|
49
|
+
: `On, but the binary is missing — ${t.install || 'install it first'}.`;
|
|
103
50
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
51
|
+
function render(data) {
|
|
52
|
+
current = data;
|
|
53
|
+
const s = data.settings;
|
|
54
|
+
dom.srvMode.value = s.mode;
|
|
55
|
+
dom.serverModeNote.textContent = MODE_NOTES[s.mode] || '';
|
|
56
|
+
dom.srvHost.value = s.host;
|
|
57
|
+
dom.srvPort.value = s.port;
|
|
58
|
+
dom.srvDomain.value = s.domain || '';
|
|
59
|
+
dom.srvHttps.checked = Boolean(s.https);
|
|
60
|
+
dom.srvHttpsStatus.textContent = data.https?.caddyInstalled
|
|
61
|
+
? `Caddy ${data.https.caddyVersion || 'installed'}. ${s.https ? 'Run `onboarder https setup` after saving.' : 'Enable HTTPS above, save, then run the command.'}`
|
|
62
|
+
: 'Caddy is not installed. Ubuntu: sudo apt install caddy; macOS: brew install caddy.';
|
|
63
|
+
dom.srvAutoOpen.checked = Boolean(s.autoOpen);
|
|
64
|
+
dom.srvName.value = s.account?.name || '';
|
|
65
|
+
dom.srvEmail.value = s.account?.email || '';
|
|
66
|
+
dom.srvTunnelCloudflare.checked = Boolean(s.tunnel?.cloudflare);
|
|
67
|
+
dom.srvTunnelTailscale.checked = Boolean(s.tunnel?.tailscale);
|
|
68
|
+
tunnelLine(dom.srvTunnelCloudflareStatus, data.tunnels?.cloudflare);
|
|
69
|
+
tunnelLine(dom.srvTunnelTailscaleStatus, data.tunnels?.tailscale);
|
|
70
|
+
dom.srvConfigPath.textContent = `Config file: ${data.configFile}`;
|
|
71
|
+
dom.srvKeyMasked.value = s.accessKeyMasked || (s.hasAccessKey ? '' : '(none set — the API refuses every call)');
|
|
72
|
+
dom.srvKeyHint.textContent = s.hasAccessKey
|
|
73
|
+
? 'Remote browsers sign in once; the key is exchanged for a secure HTTP-only session.'
|
|
74
|
+
: 'No key is set. Generate one before remote access is possible.';
|
|
75
|
+
applyModeVisibility();
|
|
76
|
+
}
|
|
77
|
+
// Mode drives which rows even make sense: local wipes the network/security
|
|
78
|
+
// fields in the schema, so asking for them here would be collecting lies.
|
|
79
|
+
function applyModeVisibility() {
|
|
80
|
+
const remote = dom.srvMode.value === 'self-hosted';
|
|
81
|
+
dom.srvKeySection.hidden = !remote;
|
|
82
|
+
dom.srvDomainField.hidden = !remote;
|
|
83
|
+
dom.srvHttpsField.hidden = !remote || !dom.srvDomain.value.trim();
|
|
84
|
+
dom.serverModeNote.textContent = MODE_NOTES[dom.srvMode.value] || '';
|
|
124
85
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'ok',
|
|
138
|
-
);
|
|
139
|
-
} catch (err) {
|
|
140
|
-
status(err.message, 'err');
|
|
86
|
+
async function open() {
|
|
87
|
+
dom.serverDrawer.hidden = false;
|
|
88
|
+
dom.serverScrim.hidden = false;
|
|
89
|
+
dom.srvFreshKeyRow.hidden = true;
|
|
90
|
+
status('Reading the server…');
|
|
91
|
+
try {
|
|
92
|
+
render(await fetchServerSettings());
|
|
93
|
+
status('');
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
status(err.message, 'err');
|
|
97
|
+
}
|
|
141
98
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
status('Rotating…');
|
|
146
|
-
try {
|
|
147
|
-
const data = await rotateServerAccessKey();
|
|
148
|
-
// The server refreshes this browser's signed session as part of rotation.
|
|
149
|
-
// The raw key is shown once for copying elsewhere, never stored locally.
|
|
150
|
-
render({ ...current, settings: data.settings });
|
|
151
|
-
dom.srvFreshKey.value = data.accessKey;
|
|
152
|
-
dom.srvFreshKeyRow.hidden = false; // render() does not know about the reveal
|
|
153
|
-
status('Rotated. The old key is dead; update every other device.', 'ok');
|
|
154
|
-
} catch (err) {
|
|
155
|
-
status(err.message, 'err');
|
|
99
|
+
function close() {
|
|
100
|
+
dom.serverDrawer.hidden = true;
|
|
101
|
+
dom.serverScrim.hidden = true;
|
|
156
102
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
103
|
+
async function save() {
|
|
104
|
+
const patch = {
|
|
105
|
+
mode: dom.srvMode.value,
|
|
106
|
+
host: dom.srvHost.value.trim() || '127.0.0.1',
|
|
107
|
+
port: Number(dom.srvPort.value),
|
|
108
|
+
autoOpen: dom.srvAutoOpen.checked,
|
|
109
|
+
account: { name: dom.srvName.value.trim(), email: dom.srvEmail.value.trim() },
|
|
110
|
+
tunnel: { cloudflare: dom.srvTunnelCloudflare.checked, tailscale: dom.srvTunnelTailscale.checked },
|
|
111
|
+
};
|
|
112
|
+
if (patch.mode === 'self-hosted') {
|
|
113
|
+
patch.domain = dom.srvDomain.value.trim();
|
|
114
|
+
patch.https = dom.srvHttps.checked;
|
|
115
|
+
}
|
|
116
|
+
status('Saving…');
|
|
117
|
+
try {
|
|
118
|
+
const data = await updateServerSettings(patch);
|
|
119
|
+
render({ ...current, settings: data.settings });
|
|
120
|
+
const restart = (data.restartRequired || []).join(' and ');
|
|
121
|
+
const httpsChanged = (data.restartRequired || []).some((key) => key === 'domain' || key === 'https');
|
|
122
|
+
status(httpsChanged
|
|
123
|
+
? 'Saved. Run `onboarder https setup` to validate the Caddyfile and reload TLS.'
|
|
124
|
+
: restart
|
|
125
|
+
? `Saved. The ${restart} change takes effect after a restart — the running socket cannot move.`
|
|
126
|
+
: 'Saved — live already.', 'ok');
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
status(err.message, 'err');
|
|
130
|
+
}
|
|
165
131
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
dom.srvFreshKey.select(); // clipboard refused — select so a Ctrl+C works
|
|
132
|
+
async function rotate() {
|
|
133
|
+
status('Rotating…');
|
|
134
|
+
try {
|
|
135
|
+
const data = await rotateServerAccessKey();
|
|
136
|
+
// The server refreshes this browser's signed session as part of rotation.
|
|
137
|
+
// The raw key is shown once for copying elsewhere, never stored locally.
|
|
138
|
+
render({ ...current, settings: data.settings });
|
|
139
|
+
dom.srvFreshKey.value = data.accessKey;
|
|
140
|
+
dom.srvFreshKeyRow.hidden = false; // render() does not know about the reveal
|
|
141
|
+
status('Rotated. The old key is dead; update every other device.', 'ok');
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
status(err.message, 'err');
|
|
145
|
+
}
|
|
181
146
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
147
|
+
async function signOut() {
|
|
148
|
+
try {
|
|
149
|
+
await logoutRemoteSession();
|
|
150
|
+
location.replace('/');
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
status(err.message, 'err');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
dom.srvMode.addEventListener('change', applyModeVisibility);
|
|
157
|
+
dom.srvDomain.addEventListener('input', applyModeVisibility);
|
|
158
|
+
dom.srvSave.addEventListener('click', save);
|
|
159
|
+
dom.srvRotate.addEventListener('click', rotate);
|
|
160
|
+
dom.srvLogout.addEventListener('click', signOut);
|
|
161
|
+
dom.serverClose.addEventListener('click', close);
|
|
162
|
+
dom.serverScrim.addEventListener('click', close);
|
|
163
|
+
dom.srvCopyKey.addEventListener('click', async () => {
|
|
164
|
+
try {
|
|
165
|
+
await navigator.clipboard.writeText(dom.srvFreshKey.value);
|
|
166
|
+
toast('Key copied');
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
dom.srvFreshKey.select(); // clipboard refused — select so a Ctrl+C works
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
open,
|
|
174
|
+
close,
|
|
175
|
+
isOpen: () => !dom.serverDrawer.hidden,
|
|
176
|
+
};
|
|
189
177
|
}
|
|
178
|
+
//# sourceMappingURL=serverSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverSettings.js","sourceRoot":"","sources":["../../src/public/js/serverSettings.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SettingsInput } from '../../shared/contracts.js';\nimport type { AppElements } from '/js/dom.js';\n// The Server drawer: the web face of the same config file the CLI wizard\n// writes. Reads come back with the key masked; saves send only the changed\n// keys; rotation reveals the new key once and signs this browser in.\n//\n// The module owns its own DOM and its own round-trips. What it borrows from\n// app.js is the drawer choreography — one scrim at a time, Escape to close —\n// which is why it returns open/close/isOpen instead of wiring the topbar\n// button itself.\n\nimport { fetchServerSettings, updateServerSettings, rotateServerAccessKey, logoutRemoteSession } from '/js/api.js';\n\n// A function declaration, not a const arrow: the import-time DOM check in\n// tests/frontend.test.js blanks top-level function bodies but reads const\n// bodies, and this module must stay importable from Node.\nfunction $(id) {\n return document.getElementById(id);\n}\n\nconst MODE_NOTES = {\n local: 'Local mode answers only this machine. No key, no network — the safe default.',\n 'self-hosted': 'Self-hosted answers whoever can reach the port, so every API call needs the access key below.',\n};\n\nexport function createServerDrawer(options: Record<string, any> = {}) {\n // Pulled out of the parameter list on purpose: the front-end static check\n // in tests/frontend.test.js only understands plain params, and `toast` must\n // show up as a declaration, not a dangling call.\n const toast = typeof options.toast === 'function' ? options.toast : (..._args: unknown[]) => {};\n const dom: Partial<AppElements> = {};\n [\n 'serverDrawer', 'serverScrim', 'serverClose', 'serverModeNote', 'srvMode', 'srvHost', 'srvPort',\n 'srvDomain', 'srvDomainField', 'srvHttps', 'srvHttpsField', 'srvHttpsStatus', 'srvAutoOpen', 'srvKeySection', 'srvKeyMasked', 'srvRotate', 'srvLogout',\n 'srvFreshKeyRow', 'srvFreshKey', 'srvCopyKey', 'srvKeyHint', 'srvName', 'srvEmail',\n 'srvTunnelCloudflare', 'srvTunnelCloudflareStatus', 'srvTunnelTailscale', 'srvTunnelTailscaleStatus',\n 'srvSave', 'srvStatus', 'srvConfigPath',\n ].forEach((id) => (dom[id] = $(id)));\n\n let current = null; // the last settings body the server sent\n\n function status(text, cls = '') {\n dom.srvStatus.className = 'drawer-status' + (cls ? ' ' + cls : '');\n dom.srvStatus.textContent = text;\n }\n\n function tunnelLine(el, t) {\n if (!t) { el.textContent = ''; return; }\n if (!t.enabled) {\n el.textContent = t.installed ? 'Off.' : `Off — and ${t.install || 'the binary is not installed'}.`;\n return;\n }\n el.textContent = t.installed\n ? `On. Start it with: ${t.command}`\n : `On, but the binary is missing — ${t.install || 'install it first'}.`;\n }\n\n function render(data) {\n current = data;\n const s = data.settings;\n dom.srvMode.value = s.mode;\n dom.serverModeNote.textContent = MODE_NOTES[s.mode] || '';\n dom.srvHost.value = s.host;\n dom.srvPort.value = s.port;\n dom.srvDomain.value = s.domain || '';\n dom.srvHttps.checked = Boolean(s.https);\n dom.srvHttpsStatus.textContent = data.https?.caddyInstalled\n ? `Caddy ${data.https.caddyVersion || 'installed'}. ${s.https ? 'Run `onboarder https setup` after saving.' : 'Enable HTTPS above, save, then run the command.'}`\n : 'Caddy is not installed. Ubuntu: sudo apt install caddy; macOS: brew install caddy.';\n dom.srvAutoOpen.checked = Boolean(s.autoOpen);\n dom.srvName.value = s.account?.name || '';\n dom.srvEmail.value = s.account?.email || '';\n dom.srvTunnelCloudflare.checked = Boolean(s.tunnel?.cloudflare);\n dom.srvTunnelTailscale.checked = Boolean(s.tunnel?.tailscale);\n tunnelLine(dom.srvTunnelCloudflareStatus, data.tunnels?.cloudflare);\n tunnelLine(dom.srvTunnelTailscaleStatus, data.tunnels?.tailscale);\n dom.srvConfigPath.textContent = `Config file: ${data.configFile}`;\n dom.srvKeyMasked.value = s.accessKeyMasked || (s.hasAccessKey ? '' : '(none set — the API refuses every call)');\n dom.srvKeyHint.textContent = s.hasAccessKey\n ? 'Remote browsers sign in once; the key is exchanged for a secure HTTP-only session.'\n : 'No key is set. Generate one before remote access is possible.';\n applyModeVisibility();\n }\n\n // Mode drives which rows even make sense: local wipes the network/security\n // fields in the schema, so asking for them here would be collecting lies.\n function applyModeVisibility() {\n const remote = dom.srvMode.value === 'self-hosted';\n dom.srvKeySection.hidden = !remote;\n dom.srvDomainField.hidden = !remote;\n dom.srvHttpsField.hidden = !remote || !dom.srvDomain.value.trim();\n dom.serverModeNote.textContent = MODE_NOTES[dom.srvMode.value] || '';\n }\n\n async function open() {\n dom.serverDrawer.hidden = false;\n dom.serverScrim.hidden = false;\n dom.srvFreshKeyRow.hidden = true;\n status('Reading the server…');\n try {\n render(await fetchServerSettings());\n status('');\n } catch (err) {\n status(err.message, 'err');\n }\n }\n\n function close() {\n dom.serverDrawer.hidden = true;\n dom.serverScrim.hidden = true;\n }\n\n\n async function save() {\n const patch: SettingsInput = {\n mode: dom.srvMode.value,\n host: dom.srvHost.value.trim() || '127.0.0.1',\n port: Number(dom.srvPort.value),\n autoOpen: dom.srvAutoOpen.checked,\n account: { name: dom.srvName.value.trim(), email: dom.srvEmail.value.trim() },\n tunnel: { cloudflare: dom.srvTunnelCloudflare.checked, tailscale: dom.srvTunnelTailscale.checked },\n };\n if (patch.mode === 'self-hosted') {\n patch.domain = dom.srvDomain.value.trim();\n patch.https = dom.srvHttps.checked;\n }\n status('Saving…');\n try {\n const data = await updateServerSettings(patch);\n render({ ...current, settings: data.settings });\n const restart = (data.restartRequired || []).join(' and ');\n const httpsChanged = (data.restartRequired || []).some((key) => key === 'domain' || key === 'https');\n status(\n httpsChanged\n ? 'Saved. Run `onboarder https setup` to validate the Caddyfile and reload TLS.'\n : restart\n ? `Saved. The ${restart} change takes effect after a restart — the running socket cannot move.`\n : 'Saved — live already.',\n 'ok',\n );\n } catch (err) {\n status(err.message, 'err');\n }\n }\n\n async function rotate() {\n status('Rotating…');\n try {\n const data = await rotateServerAccessKey();\n // The server refreshes this browser's signed session as part of rotation.\n // The raw key is shown once for copying elsewhere, never stored locally.\n render({ ...current, settings: data.settings });\n dom.srvFreshKey.value = data.accessKey;\n dom.srvFreshKeyRow.hidden = false; // render() does not know about the reveal\n status('Rotated. The old key is dead; update every other device.', 'ok');\n } catch (err) {\n status(err.message, 'err');\n }\n }\n\n async function signOut() {\n try {\n await logoutRemoteSession();\n location.replace('/');\n } catch (err) {\n status(err.message, 'err');\n }\n }\n\n dom.srvMode.addEventListener('change', applyModeVisibility);\n dom.srvDomain.addEventListener('input', applyModeVisibility);\n dom.srvSave.addEventListener('click', save);\n dom.srvRotate.addEventListener('click', rotate);\n dom.srvLogout.addEventListener('click', signOut);\n dom.serverClose.addEventListener('click', close);\n dom.serverScrim.addEventListener('click', close);\n dom.srvCopyKey.addEventListener('click', async () => {\n try {\n await navigator.clipboard.writeText(dom.srvFreshKey.value);\n toast('Key copied');\n } catch {\n dom.srvFreshKey.select(); // clipboard refused — select so a Ctrl+C works\n }\n });\n\n return {\n open,\n close,\n isOpen: () => !dom.serverDrawer.hidden,\n };\n}\n"]}
|