cmdbox 0.5.4__py3-none-any.whl → 0.6.0.1__py3-none-any.whl

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.

Potentially problematic release.


This version of cmdbox might be problematic. Click here for more details.

Files changed (148) hide show
  1. cmdbox/app/auth/signin.py +463 -303
  2. cmdbox/app/common.py +51 -3
  3. cmdbox/app/commons/loghandler.py +62 -13
  4. cmdbox/app/edge.py +5 -173
  5. cmdbox/app/edge_tool.py +177 -0
  6. cmdbox/app/feature.py +10 -9
  7. cmdbox/app/features/cli/agent_base.py +479 -0
  8. cmdbox/app/features/cli/audit_base.py +17 -5
  9. cmdbox/app/features/cli/cmdbox_audit_search.py +24 -1
  10. cmdbox/app/features/cli/cmdbox_client_file_download.py +1 -1
  11. cmdbox/app/features/cli/cmdbox_cmd_list.py +105 -0
  12. cmdbox/app/features/cli/cmdbox_cmd_load.py +104 -0
  13. cmdbox/app/features/cli/cmdbox_edge_config.py +2 -2
  14. cmdbox/app/features/cli/cmdbox_edge_start.py +1 -1
  15. cmdbox/app/features/cli/cmdbox_gui_start.py +9 -132
  16. cmdbox/app/features/cli/cmdbox_gui_stop.py +4 -21
  17. cmdbox/app/features/cli/cmdbox_server_start.py +1 -1
  18. cmdbox/app/features/cli/cmdbox_web_apikey_add.py +1 -1
  19. cmdbox/app/features/cli/cmdbox_web_apikey_del.py +1 -1
  20. cmdbox/app/features/cli/cmdbox_web_genpass.py +0 -3
  21. cmdbox/app/features/cli/cmdbox_web_group_add.py +1 -1
  22. cmdbox/app/features/cli/cmdbox_web_group_del.py +1 -1
  23. cmdbox/app/features/cli/cmdbox_web_group_edit.py +1 -1
  24. cmdbox/app/features/cli/cmdbox_web_group_list.py +1 -1
  25. cmdbox/app/features/cli/cmdbox_web_start.py +120 -104
  26. cmdbox/app/features/cli/cmdbox_web_stop.py +1 -1
  27. cmdbox/app/features/cli/cmdbox_web_user_add.py +1 -1
  28. cmdbox/app/features/cli/cmdbox_web_user_del.py +1 -1
  29. cmdbox/app/features/cli/cmdbox_web_user_edit.py +1 -1
  30. cmdbox/app/features/cli/cmdbox_web_user_list.py +1 -1
  31. cmdbox/app/features/web/cmdbox_web_agent.py +262 -0
  32. cmdbox/app/features/web/cmdbox_web_do_signout.py +3 -3
  33. cmdbox/app/features/web/cmdbox_web_exec_cmd.py +8 -3
  34. cmdbox/app/features/web/cmdbox_web_signin.py +5 -4
  35. cmdbox/app/features/web/cmdbox_web_users.py +2 -0
  36. cmdbox/app/options.py +62 -9
  37. cmdbox/app/web.py +139 -15
  38. cmdbox/extensions/features.yml +18 -0
  39. cmdbox/extensions/sample_project/sample/app/features/cli/__init__.py +0 -0
  40. cmdbox/extensions/sample_project/sample/app/features/web/__init__.py +0 -0
  41. cmdbox/extensions/sample_project/sample/extensions/features.yml +18 -0
  42. cmdbox/extensions/sample_project/sample/extensions/user_list.yml +2 -1
  43. cmdbox/extensions/sample_project/sample/logconf_sample.yml +14 -1
  44. cmdbox/extensions/user_list.yml +1 -0
  45. cmdbox/licenses/LICENSE.Authlib.1.5.2(BSD License).txt +29 -0
  46. cmdbox/licenses/LICENSE.Deprecated.1.2.18(MIT License).txt +21 -0
  47. cmdbox/licenses/LICENSE.SQLAlchemy.2.0.40(MIT License).txt +19 -0
  48. cmdbox/licenses/LICENSE.aiohappyeyeballs.2.6.1(Python Software Foundation License).txt +279 -0
  49. cmdbox/licenses/LICENSE.aiohttp.3.11.18(Apache Software License).txt +13 -0
  50. cmdbox/licenses/LICENSE.aiosignal.1.3.2(Apache Software License).txt +201 -0
  51. cmdbox/licenses/LICENSE.attrs.25.3.0(UNKNOWN).txt +21 -0
  52. cmdbox/licenses/LICENSE.cachetools.5.5.2(MIT License).txt +20 -0
  53. cmdbox/licenses/LICENSE.distro.1.9.0(Apache Software License).txt +202 -0
  54. cmdbox/licenses/LICENSE.docstring_parser.0.16(MIT License).txt +21 -0
  55. cmdbox/licenses/LICENSE.filelock.3.18.0(The Unlicense (Unlicense)).txt +24 -0
  56. cmdbox/licenses/LICENSE.frozenlist.1.6.0(Apache-2.0).txt +201 -0
  57. cmdbox/licenses/LICENSE.fsspec.2025.3.2(BSD License).txt +29 -0
  58. cmdbox/licenses/LICENSE.google-adk.0.5.0(Apache Software License).txt +202 -0
  59. cmdbox/licenses/LICENSE.google-api-python-client.2.169.0(Apache Software License).txt +201 -0
  60. cmdbox/licenses/LICENSE.google-auth-httplib2.0.2.0(Apache Software License).txt +201 -0
  61. cmdbox/licenses/LICENSE.google-auth.2.40.1(Apache Software License).txt +201 -0
  62. cmdbox/licenses/LICENSE.google-cloud-aiplatform.1.92.0(Apache 2.0).txt +202 -0
  63. cmdbox/licenses/LICENSE.google-cloud-bigquery.3.31.0(Apache Software License).txt +202 -0
  64. cmdbox/licenses/LICENSE.google-cloud-core.2.4.3(Apache Software License).txt +202 -0
  65. cmdbox/licenses/LICENSE.google-cloud-resource-manager.1.14.2(Apache Software License).txt +202 -0
  66. cmdbox/licenses/LICENSE.google-cloud-secret-manager.2.23.3(Apache Software License).txt +202 -0
  67. cmdbox/licenses/LICENSE.google-cloud-speech.2.32.0(Apache Software License).txt +202 -0
  68. cmdbox/licenses/LICENSE.google-cloud-storage.2.19.0(Apache Software License).txt +202 -0
  69. cmdbox/licenses/LICENSE.google-cloud-trace.1.16.1(Apache Software License).txt +202 -0
  70. cmdbox/licenses/LICENSE.google-crc32c.1.7.1(Apache 2.0).txt +202 -0
  71. cmdbox/licenses/LICENSE.google-genai.1.14.0(Apache Software License).txt +202 -0
  72. cmdbox/licenses/LICENSE.google-resumable-media.2.7.2(Apache Software License).txt +202 -0
  73. cmdbox/licenses/LICENSE.googleapis-common-protos.1.70.0(Apache Software License).txt +202 -0
  74. cmdbox/licenses/LICENSE.graphviz.0.20.3(MIT License).txt +21 -0
  75. cmdbox/licenses/LICENSE.grpc-google-iam-v1.0.14.2(Apache Software License).txt +202 -0
  76. cmdbox/licenses/LICENSE.grpcio-status.1.71.0(Apache Software License).txt +610 -0
  77. cmdbox/licenses/LICENSE.grpcio.1.71.0(Apache Software License).txt +610 -0
  78. cmdbox/licenses/LICENSE.httpcore.1.0.9(BSD License).txt +27 -0
  79. cmdbox/licenses/LICENSE.httplib2.0.22.0(MIT License).txt +23 -0
  80. cmdbox/licenses/LICENSE.httpx-sse.0.4.0(MIT).txt +21 -0
  81. cmdbox/licenses/LICENSE.httpx.0.28.1(BSD License).txt +12 -0
  82. cmdbox/licenses/LICENSE.huggingface-hub.0.31.1(Apache Software License).txt +201 -0
  83. cmdbox/licenses/LICENSE.importlib_metadata.8.6.1(Apache Software License).txt +202 -0
  84. cmdbox/licenses/LICENSE.jiter.0.9.0(MIT License).txt +1 -0
  85. cmdbox/licenses/LICENSE.jsonschema-specifications.2025.4.1(UNKNOWN).txt +19 -0
  86. cmdbox/licenses/LICENSE.jsonschema.4.23.0(MIT License).txt +19 -0
  87. cmdbox/licenses/LICENSE.litellm.1.69.0(MIT License).txt +26 -0
  88. cmdbox/licenses/LICENSE.mcp.1.8.0(MIT License).txt +21 -0
  89. cmdbox/licenses/LICENSE.multidict.6.4.3(Apache Software License).txt +13 -0
  90. cmdbox/licenses/LICENSE.openai.1.75.0(Apache Software License).txt +201 -0
  91. cmdbox/licenses/LICENSE.opentelemetry-api.1.33.0(Apache Software License).txt +201 -0
  92. cmdbox/licenses/LICENSE.opentelemetry-exporter-gcp-trace.1.9.0(Apache Software License).txt +201 -0
  93. cmdbox/licenses/LICENSE.opentelemetry-resourcedetector-gcp.1.9.0a0(Apache Software License).txt +201 -0
  94. cmdbox/licenses/LICENSE.opentelemetry-sdk.1.33.0(Apache Software License).txt +201 -0
  95. cmdbox/licenses/LICENSE.opentelemetry-semantic-conventions.0.54b0(Apache Software License).txt +201 -0
  96. cmdbox/licenses/LICENSE.propcache.0.3.1(Apache Software License).txt +202 -0
  97. cmdbox/licenses/LICENSE.proto-plus.1.26.1(Apache Software License).txt +202 -0
  98. cmdbox/licenses/LICENSE.protobuf.5.29.4(3-Clause BSD License).txt +32 -0
  99. cmdbox/licenses/LICENSE.pyasn1.0.6.1(BSD License).txt +24 -0
  100. cmdbox/licenses/LICENSE.pyasn1_modules.0.4.2(BSD License).txt +24 -0
  101. cmdbox/licenses/LICENSE.pydantic-settings.2.9.1(MIT License).txt +21 -0
  102. cmdbox/licenses/LICENSE.pyparsing.3.2.3(MIT License).txt +18 -0
  103. cmdbox/licenses/LICENSE.python-dateutil.2.9.0.post0(Apache Software License; BSD License).txt +54 -0
  104. cmdbox/licenses/LICENSE.referencing.0.36.2(UNKNOWN).txt +19 -0
  105. cmdbox/licenses/LICENSE.regex.2024.11.6(Apache Software License).txt +208 -0
  106. cmdbox/licenses/LICENSE.rpds-py.0.24.0(MIT).txt +19 -0
  107. cmdbox/licenses/LICENSE.rsa.4.9.1(Apache Software License).txt +13 -0
  108. cmdbox/licenses/LICENSE.shapely.2.1.0(BSD License).txt +29 -0
  109. cmdbox/licenses/LICENSE.sse-starlette.2.3.4(BSD License).txt +27 -0
  110. cmdbox/licenses/LICENSE.tiktoken.0.9.0(MIT License).txt +21 -0
  111. cmdbox/licenses/LICENSE.tokenizers.0.21.1(Apache Software License).txt +1 -0
  112. cmdbox/licenses/LICENSE.tqdm.4.67.1(MIT License; Mozilla Public License 2.0 (MPL 2.0)).txt +49 -0
  113. cmdbox/licenses/LICENSE.tzlocal.5.3.1(MIT License).txt +19 -0
  114. cmdbox/licenses/LICENSE.uritemplate.4.1.1(Apache Software License; BSD License).txt +3 -0
  115. cmdbox/licenses/LICENSE.wrapt.1.17.2(BSD License).txt +24 -0
  116. cmdbox/licenses/LICENSE.yarl.1.20.0(Apache Software License).txt +202 -0
  117. cmdbox/licenses/files.txt +104 -11
  118. cmdbox/logconf_audit.yml +16 -3
  119. cmdbox/logconf_client.yml +16 -3
  120. cmdbox/logconf_cmdbox.yml +16 -3
  121. cmdbox/logconf_edge.yml +16 -3
  122. cmdbox/logconf_gui.yml +15 -2
  123. cmdbox/logconf_server.yml +15 -2
  124. cmdbox/logconf_web.yml +15 -2
  125. cmdbox/version.py +3 -2
  126. cmdbox/web/agent.html +263 -0
  127. cmdbox/web/assets/cmdbox/agent.js +338 -0
  128. cmdbox/web/assets/cmdbox/common.js +1111 -1020
  129. cmdbox/web/assets/cmdbox/main.js +17 -3
  130. cmdbox/web/assets/cmdbox/signin.js +4 -4
  131. cmdbox/web/assets/filer/filer.js +4 -2
  132. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/METADATA +69 -26
  133. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/RECORD +148 -67
  134. /cmdbox/licenses/{LICENSE.charset-normalizer.3.4.1(MIT License).txt → LICENSE.charset-normalizer.3.4.2(MIT License).txt} +0 -0
  135. /cmdbox/licenses/{LICENSE.click.8.1.8(BSD License).txt → LICENSE.click.8.2.0(UNKNOWN).txt} +0 -0
  136. /cmdbox/licenses/{LICENSE.cryptography.44.0.2(Apache Software License; BSD License).txt → LICENSE.cryptography.44.0.3(Apache Software License; BSD License).txt} +0 -0
  137. /cmdbox/licenses/{LICENSE.importlib_metadata.8.7.0(Apache Software License).txt → LICENSE.google-api-core.2.24.2(Apache Software License).txt} +0 -0
  138. /cmdbox/licenses/{LICENSE.greenlet.3.2.1(MIT AND Python-2.0).txt → LICENSE.greenlet.3.2.2(MIT AND Python-2.0).txt} +0 -0
  139. /cmdbox/licenses/{LICENSE.psycopg-binary.3.2.6(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE.psycopg-binary.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt} +0 -0
  140. /cmdbox/licenses/{LICENSE.psycopg.3.2.6(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE.psycopg.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt} +0 -0
  141. /cmdbox/licenses/{LICENSE.pydantic.2.11.3(MIT License).txt → LICENSE.pydantic.2.11.4(MIT License).txt} +0 -0
  142. /cmdbox/licenses/{LICENSE.pydantic_core.2.33.1(MIT License).txt → LICENSE.pydantic_core.2.33.2(MIT License).txt} +0 -0
  143. /cmdbox/licenses/{LICENSE.redis.5.2.1(MIT License).txt → LICENSE.redis.6.0.0(MIT License).txt} +0 -0
  144. /cmdbox/licenses/{LICENSE.snowballstemmer.2.2.0(BSD License).txt → LICENSE.snowballstemmer.3.0.1(BSD License).txt} +0 -0
  145. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/LICENSE +0 -0
  146. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/WHEEL +0 -0
  147. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/entry_points.txt +0 -0
  148. {cmdbox-0.5.4.dist-info → cmdbox-0.6.0.1.dist-info}/top_level.txt +0 -0
cmdbox/web/agent.html ADDED
@@ -0,0 +1,263 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="UTF-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <style type="text/css">
6
+ .card-hover:hover {
7
+ box-shadow: 0 0 8px gray;
8
+ }
9
+ .filer-pane-divider {
10
+ border: 1px solid var(--bs-border-color-translucent) !important;
11
+ /**background-color: #F0F0F0 !important;*/
12
+ border-radius: 1px;
13
+ /*left: 50%;*/
14
+ }
15
+ .chat-container {
16
+ overflow-y: auto;
17
+ background-color: var(--bs-body-bg);
18
+ }
19
+ .message {
20
+ padding: 10px;
21
+ /**border: 1px solid var(--bs-border-color-translucent);*/
22
+ margin-bottom: 10px;
23
+ border-radius: 5px;
24
+ clear: both;
25
+ }
26
+ .user-message {
27
+ background-color: var(--bs-tertiary-bg);
28
+ color: var(--bs-body-color);
29
+ /**float: right;*/
30
+ border-bottom-left-radius: 24px;
31
+ border-bottom-right-radius: 24px;
32
+ border-top-left-radius: 24px;
33
+ border-top-right-radius: 4px;
34
+ }
35
+ .bot-message {
36
+ background-color: var(--bs-body-bg);
37
+ color: var(--bs-body-color);
38
+ float: left;
39
+ }
40
+ .chat-input {
41
+ border-radius: 16px;
42
+ border: 1px solid var(--bs-border-color);
43
+ }
44
+ :root {
45
+ --cmdbox-width: 800px;
46
+ }
47
+ pre {
48
+ width: var(--cmdbox-width);
49
+ overflow-wrap: break-all;
50
+ }
51
+ .btn_hover {
52
+ border-radius: 24px !important;
53
+ }
54
+ .btn_hover:hover {
55
+ background-color: var(--bs-tertiary-bg) !important;
56
+ }
57
+ </style>
58
+ </head>
59
+ <body lang="ja" class="overflow-hidden p-2" style="background-color:rgb(33, 37, 41)">
60
+ <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
61
+ <symbol id="svg_signin_ico" viewBox="0 0 16 16">
62
+ <path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"></path>
63
+ <path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"></path>
64
+ </symbol>
65
+ <symbol id="svg_window_stack" viewBox="0 0 16 16">
66
+ <path d="M4.5 6a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1ZM6 6a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1Zm2-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z"/>
67
+ <path d="M12 1a2 2 0 0 1 2 2 2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2 2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h10ZM2 12V5a2 2 0 0 1 2-2h9a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1Zm1-4v5a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V8H3Zm12-1V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v2h12Z"/>
68
+ </symbol>
69
+ <symbol id="svg_window" viewBox="0 0 16 16">
70
+ <path d="M2.5 4a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm2-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm1 .5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1z"/>
71
+ <path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H2zm13 2v2H1V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1zM2 14a1 1 0 0 1-1-1V6h14v7a1 1 0 0 1-1 1H2z"/>
72
+ </symbol>
73
+ <symbol id="btn_x" viewBox="0 0 16 16">
74
+ <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>
75
+ </symbol>
76
+ <symbol id="btn_chat_text" viewBox="0 0 16 16">
77
+ <path d="M2.678 11.894a1 1 0 0 1 .287.801 11 11 0 0 1-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 0 1 .71-.074A8 8 0 0 0 8 14c3.996 0 7-2.807 7-6s-3.004-6-7-6-7 2.808-7 6c0 1.468.617 2.83 1.678 3.894m-.493 3.905a22 22 0 0 1-.713.129c-.2.032-.352-.176-.273-.362a10 10 0 0 0 .244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9 9 0 0 1-2.347-.306c-.52.263-1.639.742-3.468 1.105"/>
78
+ <path d="M4 5.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8m0 2.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5"/>
79
+ </symbol>
80
+ <symbol id="btn_plus" viewBox="0 0 16 16">
81
+ <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
82
+ </symbol>
83
+ <symbol id="btn_send" viewBox="0 0 16 16">
84
+ <path d="M15.854.146a.5.5 0 0 1 .11.54l-5.819 14.547a.75.75 0 0 1-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 0 1 .124-1.33L15.314.037a.5.5 0 0 1 .54.11ZM6.636 10.07l2.761 4.338L14.13 2.576zm6.787-8.201L1.591 6.602l4.339 2.76z"/>
85
+ </symbol>
86
+ <symbol id="svg_justify_left" viewBox="0 0 16 16">
87
+ <path fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5"/>
88
+ </symbol>
89
+ <symbol id="btn_three_dots_vertical" viewBox="0 0 16 16">
90
+ <path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
91
+ </symbol>
92
+ </svg>
93
+ <!-- ナビゲーションバー -->
94
+ <nav class="navbar navbar-expand-sm fixed-top p-2">
95
+ <div class="container-fluid">
96
+ <a class="navbar-brand" href="#">cmdbox</a>
97
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
98
+ <span class="navbar-toggler-icon"></span>
99
+ </button>
100
+ <div class="collapse navbar-collapse" id="navbarNavDropdown">
101
+ <ul class="navbar-nav me-auto">
102
+ <li class="nav-item dropdown">
103
+ <a class="nav-link dropdown-toggle" href="#" id="viewMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
104
+ View
105
+ </a>
106
+ <ul class="dropdown-menu viewmenu">
107
+ <li class="nav-item dropdown">
108
+ <span class="dropdown-item">
109
+ Change Dark Mode
110
+ <select class="d-inline-block change_color_mode" onchange="cmdbox.change_color_mode($(this).val());">
111
+ <option value="dark" selected>Dark</option>
112
+ <option value="midnight">midnight</option>
113
+ <option value="deepsea">deepsea</option>
114
+ <option value="verdant">verdant</option>
115
+ <option value="bumblebee">bumblebee</option>
116
+ <option value="crimson">crimson</option>
117
+ <option value="light">light</option>
118
+ </select>
119
+ </span>
120
+ </li>
121
+ </ul>
122
+ </li>
123
+ <li class="nav-item dropdown">
124
+ <a class="nav-link dropdown-toggle" href="#" id="aboutMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
125
+ About
126
+ </a>
127
+ <ul class="dropdown-menu aboutmenu" aria-labelledby="aboutMenuLink">
128
+ <li><a class="dropdown-item" href="#" onclick="$(`#versions_modal`).modal(`show`);">Versions</a></li>
129
+ </ul>
130
+ </li>
131
+ </ul>
132
+ <div class="d-none dropdown user_info">
133
+ <a href="#" class="d-block link-body-emphasis text-decoration-none dropdown-toggle show" data-bs-toggle="dropdown" aria-expanded="true" style="fill:gray;">
134
+ <svg class="m-1" width="24" height="24" viewBox="0 0 16 16">
135
+ <use href="#svg_signin_ico"></use>
136
+ </svg>
137
+ <span class="username">UserName</span>
138
+ </a>
139
+ <ul class="dropdown-menu text-small shadow" style="position: absolute; inset: 0px 0px auto auto; margin: 0px; transform: translate(0px, 34px);" data-popper-placement="bottom-end">
140
+ <div class="user_info_note ps-3 pe-3"></div>
141
+ <li><hr class="dropdown-divider"></li>
142
+ </ul>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </nav>
147
+ <!-- メインコンテナ -->
148
+ <div id="main_container" class="container-fluid overflow-auto split-pane fixed-left" style="margin-top:66px;height:calc(100vh - 120px);">
149
+ <!-- 履歴側ペイン -->
150
+ <div id="left_container" class="split-pane-component filer-pane-left" style="width:15%;">
151
+ <div id="newchat_container" class="w-100 d-flex justify-content-center">
152
+ <button id="btn_newchat" class="btn_hover btn me-3 p-2" type="button" style="border:0px;">
153
+ <svg class="bi bi-plus" width="24" height="24" fill="currentColor"><use href="#btn_plus"></use></svg>
154
+ <span class="btn_text">New Chat&nbsp;</span>
155
+ </button>
156
+ </div>
157
+ <h6 style="float:left;">
158
+ Histories
159
+ </h6>
160
+ <div id="history_container" class="w-100 d-flex justify-content-center" style="height:calc(100% - 80px);overflow-y:auto;">
161
+ <div id="histories" class="w-100 p-2">
162
+ </div>
163
+ </div>
164
+ </div>
165
+ <!-- 左右のスプリッター -->
166
+ <div class="split-pane-divider filer-pane-divider" style="left:15%;"></div>
167
+ <!-- チャット側ペイン -->
168
+ <div id="right_container" class="split-pane-component chat-container " style="left:15%;">
169
+ <div id="message_container" class="w-100 d-flex justify-content-center" style="height:calc(100% - 80px);overflow-y:auto;">
170
+ <div id="messages" class="ps-2 pe-2" style="width:var(--cmdbox-width);">
171
+ </div>
172
+ </div>
173
+ <div class="w-100 d-flex justify-content-center">
174
+ <div class="chat-input mt-2" style="width:800px;">
175
+ <div class="chat-group w-100 p-2">
176
+ <textarea id="user_msg" class="form-control d-inline-block align-middle" rows="1" style="width:calc(100% - 60px);border:0px;box-shadow:none;resize:none;field-sizing:content;"></textarea>
177
+ <button id="btn_user_msg" class="btn btn_hover" type="button" style="border:0px;" disabled="disabled">
178
+ <svg class="bi bi-send" width="24" height="24" fill="currentColor"><use href="#btn_send"></use></svg>
179
+ </button>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ <form id="filter_form" class="d-none filer_form">
185
+ <input name="filer_host" type="hidden" class="filer_host">
186
+ <input name="filer_port" type="hidden" class="filer_port">
187
+ <input name="filer_password" type="hidden" class="filer_password">
188
+ <input name="filer_svname" type="hidden" class="filer_svname">
189
+ <input name="filer_scope" type="hidden" class="filer_scope">
190
+ <input name="filer_client_data" type="hidden" class="filer_client_data">
191
+ </form>
192
+ </div>
193
+ <!-- versionsモーダル -->
194
+ <div id="versions_modal" class="modal" tabindex="-1">
195
+ <div class="modal-dialog modal-lg">
196
+ <form id="version_form" class="modal-content novalidate">
197
+ <div class="modal-header">
198
+ <h5 class="modal-title">
199
+ Versions
200
+ </h5>
201
+ <button type="button" class="btn btn_window_stack">
202
+ <svg width="16" height="16" fill="currentColor" class="bi bi-window-stack">
203
+ <use href="#svg_window_stack"></use>
204
+ </svg>
205
+ </button>
206
+ <button type="button" class="btn btn_window">
207
+ <svg width="16" height="16" fill="currentColor" class="bi bi-window">
208
+ <use href="#svg_window"></use>
209
+ </svg>
210
+ </button>
211
+ <button type="button" class="btn btn_close p-0 m-0" data-bs-dismiss="modal" aria-label="Close" style="margin-left: 0px;">
212
+ <svg class="bi bi-x" width="24" height="24" fill="currentColor"><use href="#btn_x"></use></svg>
213
+ </button>
214
+ </div>
215
+ <div class="modal-body">
216
+ <ul class="nav nav-tabs version-tabs" role="tablist"></ul>
217
+ <div class="tab-content version-content"></div>
218
+ </div>
219
+ <div class="modal-footer">
220
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
221
+ </div>
222
+ </form>
223
+ </div>
224
+ </div>
225
+ <!-- ローディングマスク -->
226
+ <div id="loading" class="position-absolute top-0 start-0 w-100 h-100 d-none" style="background:rgba(0, 0, 0, 0.3);z-index:10000;">
227
+ <div class="text-center position-absolute top-50 start-50 w-100 translate-middle">
228
+ <div class="spinner-border text-light" role="status">
229
+ <span class="sr-only"></span>
230
+ </div>
231
+ <div>
232
+ <button type="button" class="btn btn-outline-danger mt-3 bbforce">Back by force</button>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ <!-- フッター -->
237
+ <footer class="fixed-bottom text-center p-2 copyright"></footer>
238
+ </body>
239
+ <script type="text/javascript">
240
+ // jqueryの読込み完了までbodyの背景色を設定
241
+ document.querySelector(`body`).style.setProperty(`--bs-body-bg`, `#212529`);
242
+ document.querySelector(`body`).style.setProperty(`--bs-tertiary-bg`, `#2b3035`);
243
+ document.querySelector(`body`).style.setProperty(`--bs-tertiary-bg-rgb`, `43,48,53`);
244
+ document.querySelector(`body`).style.setProperty(`--bs-secondary-bg`, `#343a40`);
245
+ document.addEventListener('DOMContentLoaded', () => {
246
+ document.querySelector(`body`).style.setProperty(`--bs-body-bg`, null);
247
+ document.querySelector(`body`).style.setProperty(`--bs-tertiary-bg`, null);
248
+ document.querySelector(`body`).style.setProperty(`--bs-tertiary-bg-rgb`, null);
249
+ document.querySelector(`body`).style.setProperty(`--bs-secondary-bg`, null);
250
+ });
251
+ </script>
252
+ <link rel="stylesheet" href="assets/bootstrap/bootstrap.min.5.3.0.css">
253
+ <link rel="stylesheet" href="assets/cmdbox/color_mode.css">
254
+ <link rel="stylesheet" href="assets/split-pane/split-pane.css">
255
+ <script type="text/javascript" src="assets/bootstrap/bootstrap.bundle.min.5.3.0.js"></script>
256
+ <script type="text/javascript" src="assets/jquery/jquery.min.3.2.0.js"></script>
257
+ <script type="text/javascript" src="assets/jquery-ui/jquery-ui.min.js"></script>
258
+ <script type="text/javascript" src="assets/jquery-resizable/jquery-resizable.min.js"></script>
259
+ <script type="text/javascript" src="assets/split-pane/split-pane.js"></script>
260
+ <script type="text/javascript" src="assets/cmdbox/common.js"></script>
261
+ <script type="text/javascript" src="assets/cmdbox/view_result.js"></script>
262
+ <script type="text/javascript" src="assets/cmdbox/agent.js"></script>
263
+ </html>
@@ -0,0 +1,338 @@
1
+ const agent = {};
2
+ agent.chat_reconnectInterval_handler = null;
3
+ agent.chat_callback_ping_handler = null;
4
+ agent.create_user_message = (messages, msg) => {
5
+ const user_msg_row = $(`<div class="message" style="float:right;"></div>`).appendTo(messages);
6
+ const user_message = $(`<div class="message user-message d-inline-block" style="width:calc(100% - 48px);"></div>`).appendTo(user_msg_row);
7
+ $(`<div class="d-inline-block"></div>`).appendTo(user_message).text(msg);
8
+ $(`<a class="d-inline-block align-top" style="fill:gray;"><svg class="align-top ms-3" width="32" height="32" viewBox="0 0 16 16">`
9
+ +`<use href="#svg_signin_ico"></use></svg></a>`).appendTo(user_msg_row);
10
+ };
11
+ agent.create_agent_message = (messages, message_id) => {
12
+ const bot_message = $(`<div class="message bot-message"></div>`).appendTo(messages);
13
+ $(`<img class="icon-logo align-top me-3" src="${cmdbox.logoicon_src}" width="32" height="32"/>`).appendTo(bot_message);
14
+ const txt = $(`<div id="${message_id}" class="d-inline-block" style="width:calc(100% - 48px);"></div>`).appendTo(bot_message);
15
+ return txt;
16
+ }
17
+ agent.format_agent_message = (container, messages, txt, message) => {
18
+ // メッセージが空の場合は何もしない
19
+ if (!message || message.length <= 0) return;
20
+ txt.html('');
21
+ const regs_start = /```json/s;
22
+ const regs_json = /```json(?!```)+/s;
23
+ const regs_end = /```/s;
24
+ while (message && message.length > 0) {
25
+ try {
26
+ // JSON開始部分を探す
27
+ let start = message.match(regs_start);
28
+ if (!start || start.length < 0) {
29
+ // JSON開始部分が無い場合はそのまま表示
30
+ const msg = message.replace(/\n/g, '<br/>');
31
+ txt.append(msg);
32
+ break;
33
+ }
34
+ start = message.substring(0, start.index);
35
+ if (start) txt.append(start.replace(/\n/g, '<br/>'));
36
+ message = message.replace(start+regs_start.source, '');
37
+
38
+ // JSON内容部分を探す
39
+ let jbody = message.match(regs_end);
40
+ if (!jbody || jbody.length < 0) {
41
+ // JSON内容部分が無い場合はそのまま表示
42
+ const msg = message.replace(/\n/g, '<br/>');
43
+ txt.append(msg);
44
+ break;
45
+ }
46
+ jbody = message.substring(0, jbody.index);
47
+ jobj = eval(`(${jbody})`);
48
+ message = message.replace(jbody+regs_end.source, '');
49
+ const rand = cmdbox.random_string(16);
50
+ txt.append(`<span id="${rand}"/>`);
51
+ agent.recursive_json_parse(jobj);
52
+ render_result_func(txt.find(`#${rand}`), jobj, 100);
53
+ } catch (e) {
54
+ const msg = message.replace(/\n/g, '<br/>');
55
+ txt.append(msg);
56
+ break;
57
+ }
58
+ }
59
+ // メッセージ一覧を一番下までスクロール
60
+ container.scrollTop(container.prop('scrollHeight'));
61
+ const msg_width = messages.prop('scrollWidth');
62
+ if (msg_width > 800) {
63
+ // メッセージ一覧の幅が800pxを超えたら、メッセージ一覧の幅を調整
64
+ document.documentElement.style.setProperty('--cmdbox-width', `${msg_width}px`);
65
+ }
66
+ };
67
+ agent.recursive_json_parse = (jobj) => {
68
+ Object.keys(jobj).forEach((key) => {
69
+ if (!jobj[key]) return; // nullやundefinedは無視
70
+ if (typeof jobj[key] === 'function') {
71
+ delete jobj[key]; // 関数は削除
72
+ return;
73
+ }
74
+ if (typeof jobj[key] === 'string') {
75
+ try {
76
+ const val = eval(`(${jobj[key]})`);
77
+ if (val && typeof val === 'object' && !Array.isArray(val))
78
+ for (const v of Object.values(val))
79
+ if (v && typeof v === 'function') return; // 関数は無視
80
+ else if (val && Array.isArray(val))
81
+ for (const v of val)
82
+ if (v && typeof v === 'function') return; // 関数は無視
83
+ jobj[key] = val;
84
+ agent.recursive_json_parse(jobj[key]);
85
+ } catch (e) {
86
+ console.debug(`Fail parsing JSON string: ${jobj[key]}`, e);
87
+ }
88
+ }
89
+ if (typeof jobj[key] === 'object' && !Array.isArray(jobj[key])) {
90
+ // オブジェクトの場合は再帰的に処理
91
+ agent.recursive_json_parse(jobj[key]);
92
+ }
93
+ });
94
+ };
95
+ agent.init_form = async () => {
96
+ const container = $('#message_container');
97
+ const histories = $('#histories');
98
+ const messages = $('#messages');
99
+ const ping_interval = 5000; // pingの間隔
100
+ const max_reconnect_count = 60000/ping_interval*1; // 最大再接続回数
101
+ agent.chat_reconnect_count = 0;
102
+ agent.chat = (session_id) => {
103
+ // ws再接続のためのインターバル初期化
104
+ if (agent.chat_reconnectInterval_handler) {
105
+ clearInterval(agent.chat_reconnectInterval_handler);
106
+ }
107
+ // wsのpingのためのインターバル初期化
108
+ if (agent.chat_callback_ping_handler) {
109
+ clearInterval(agent.chat_callback_ping_handler);
110
+ }
111
+ messages.attr('data-session_id', session_id);
112
+ const btn_user_msg = $('#btn_user_msg');
113
+ const user_msg = $('#user_msg');
114
+ let message_id = null;
115
+ btn_user_msg.prop('disabled', true); // 初期状態で送信ボタンを無効化
116
+ // 送信ボタンのクリックイベント
117
+ btn_user_msg.off('click').on('click', async () => {
118
+ const msg = user_msg.val();
119
+ if (msg.length <= 0) return;
120
+ user_msg.val('');
121
+ // 入力内容をユーザーメッセージとして表示
122
+ agent.create_user_message(messages, msg);
123
+ agent.create_history(histories, session_id, msg);
124
+ // エージェント側のメッセージ読込中を表示
125
+ if (!message_id) {
126
+ message_id = cmdbox.random_string(16);
127
+ const txt = agent.create_agent_message(messages, message_id);
128
+ cmdbox.show_loading(txt);
129
+ }
130
+ // メッセージを送信
131
+ ws.send(msg);
132
+ // セッション一覧を再表示
133
+ agent.list_sessions();
134
+ // メッセージ一覧を一番下までスクロール
135
+ container.scrollTop(container.prop('scrollHeight'));
136
+ });
137
+ // ws接続
138
+ const protocol = window.location.protocol.endsWith('s:') ? 'wss' : 'ws';
139
+ const host = window.location.hostname;
140
+ const port = window.location.port;
141
+ const path = window.location.pathname;
142
+ const ws = new WebSocket(`${protocol}://${host}:${port}${path}/chat/ws/${session_id}`);
143
+ // エージェントからのメッセージ受信時の処理
144
+ ws.onmessage = (event) => {
145
+ const packet = JSON.parse(event.data);
146
+ console.log(packet);
147
+ if (packet.turn_complete && packet.turn_complete) {
148
+ return;
149
+ }
150
+ let txt;
151
+ if (!message_id) {
152
+ // エージェント側の表示枠が無かったら追加
153
+ message_id = cmdbox.random_string(16);
154
+ txt = agent.create_agent_message(messages, message_id);
155
+ } else {
156
+ txt = $(`#${message_id}`);
157
+ }
158
+ txt.html('');
159
+ message_id = null;
160
+ agent.format_agent_message(container, messages, txt, packet.message);
161
+ };
162
+ ws.onopen = () => {
163
+ const ping = () => {
164
+ ws.send('ping');
165
+ agent.chat_reconnect_count = 0; // pingが成功したら再接続回数をリセット
166
+ };
167
+ btn_user_msg.prop('disabled', false);
168
+ agent.chat_callback_ping_handler = setInterval(() => {ping();}, ping_interval);
169
+ };
170
+ ws.onerror = (e) => {
171
+ console.error(`Websocket error: ${e}`);
172
+ clearInterval(agent.chat_callback_ping_handler);
173
+ };
174
+ ws.onclose = () => {
175
+ clearInterval(agent.chat_callback_ping_handler);
176
+ if (agent.chat_reconnect_count >= max_reconnect_count) {
177
+ clearInterval(agent.chat_reconnectInterval_handler);
178
+ cmdbox.message({'error':'Connection to the agent has failed for several minutes. Please reload to resume reconnection.'});
179
+ const rand = cmdbox.random_string(8);
180
+ location.href = `../signin/agent?r=${rand}`;
181
+ return;
182
+ }
183
+ agent.chat_reconnect_count++;
184
+ agent.chat_reconnectInterval_handler = setInterval(() => {
185
+ agent.chat(session_id);
186
+ }, ping_interval);
187
+ };
188
+ };
189
+ const user_msg = $('#user_msg');
190
+ user_msg.off('keydown').on('keydown', (e) => {
191
+ // Ctrl+Enterで送信
192
+ if (e.key === 'Enter' && e.ctrlKey) {
193
+ e.preventDefault();
194
+ $('#btn_user_msg').click();
195
+ container.css('height', `calc(100% - ${user_msg.prop('scrollHeight')}px - 42px)`);
196
+ return
197
+ }
198
+ });
199
+ user_msg.off('input').on('input', (e) => {
200
+ // テキストエリアのリサイズに合わせてメッセージ一覧の高さを調整
201
+ container.css('height', `calc(100% - ${user_msg.prop('scrollHeight')}px - 42px)`);
202
+ });
203
+ const btn_newchat = $('#btn_newchat');
204
+ btn_newchat.off('click').on('click', async () => {
205
+ // メッセージ一覧をクリア
206
+ messages.html('');
207
+ // 新しいセッションを作成
208
+ const session_id = cmdbox.random_string(16);
209
+ agent.chat(session_id);
210
+ });
211
+ // テキストエリアのリサイズに合わせてメッセージ一覧の高さを調整
212
+ container.scrollTop(container.prop('scrollHeight'));
213
+ // セッション一覧を表示
214
+ agent.list_sessions();
215
+ // 新しいセッションでチャットを開始
216
+ const session_id = cmdbox.random_string(16);
217
+ agent.chat(session_id);
218
+ };
219
+ agent.list_sessions = async (session_id) => {
220
+ const formData = new FormData();
221
+ session_id && formData.append('session_id', session_id);
222
+ const histories = $('#histories');
223
+ const res = await fetch('agent/session/list', {method: 'POST', body: formData});
224
+ if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
225
+ res.json().then((res) => {
226
+ if (!res['success']) return;
227
+ histories.html('');
228
+ res['success'].forEach(async (row) => {
229
+ if (!row['events'] || row['events'].length <= 0) return;
230
+ const msg = row['events'][0]['text'];
231
+ const history = agent.create_history(histories, row['id'], msg);
232
+ });
233
+ });
234
+ }
235
+ agent.create_history = (histories, session_id, msg) => {
236
+ if (histories.find(`#${session_id}`).length > 0) return;
237
+ msg = cell_chop(msg, 300);
238
+ const history = $(`<a id="${session_id}" href="#" class="history pt-2 pb-1 d-block btn_hover"></a>`).appendTo(histories);
239
+ $(`<span class="d-inline-block align-top ms-2 me-2" style="fill:gray;"><svg class="align-top" width="24" height="24" viewBox="0 0 16 16">`
240
+ +`<use href="#svg_justify_left"></use></svg></span>`).appendTo(history);
241
+ $(`<div class="d-inline-block mb-2" style="width:calc(100% - 88px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"></div>`).appendTo(history).text(msg);
242
+ const btn = $(`<button class="btn d-inline-block align-top pt-1 btn_hover" style="fill:gray;"><svg class="align-top" width="16" height="16" viewBox="0 0 16 16">`
243
+ +`<use href="#btn_three_dots_vertical"></use></svg><ul class="dropdown-menu"/></button>`).appendTo(history);
244
+ btn.find('.dropdown-menu').append(`<li><a class="dropdown-item delete" href="#">Delete</a></li>`);
245
+ btn.off('click').on('click', (e) => {
246
+ e.preventDefault();
247
+ e.stopPropagation();
248
+ histories.find('.dropdown-menu').hide();
249
+ btn.find('.dropdown-menu').css('left','calc(100% - 180px)').show();
250
+ });
251
+ btn.find('.dropdown-menu .delete').off('click').on('click',(e)=>{
252
+ if (!window.confirm('Are you sure you want to delete this session?')) return;
253
+ // セッション削除ボタンのクリックイベント
254
+ e.preventDefault();
255
+ e.stopPropagation();
256
+ agent.delete_session(session_id).then((res) => {
257
+ if (res['success']) {
258
+ history.remove();
259
+ const sid = messages.attr('data-session_id');
260
+ if (sid == session_id) {
261
+ // 削除したセッションが現在のセッションだった場合は、メッセージ一覧をクリア
262
+ messages.html('');
263
+ agent.chat(cmdbox.random_string(16)); // 新しいセッションを開始
264
+ }
265
+ agent.list_sessions();
266
+ } else {
267
+ cmdbox.message({'error':res['error'] || 'Failed to delete session.'});
268
+ }
269
+ });
270
+ });
271
+ history.off('click').on('click', async (e) => {
272
+ // セッションを選択したときの処理
273
+ e.preventDefault();
274
+ agent.chat(session_id);
275
+ const formData = new FormData();
276
+ formData.append('session_id', session_id);
277
+ const res = await fetch('agent/session/list', {method: 'POST', body: formData});
278
+ if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
279
+ res.json().then((res) => {
280
+ if (!res['success'] || res['success'].length<=0) {
281
+ cmdbox.message({'error':'No messages found for this session.'});
282
+ return;
283
+ }
284
+ const session = res['success'][0];
285
+ if (!session['events'] || session['events'].length <= 0) {
286
+ cmdbox.message({'error':'No messages found for this session.'});
287
+ return;
288
+ }
289
+ const container = $('#message_container');
290
+ const messages = $('#messages');
291
+ messages.html('');
292
+ session['events'].forEach((event) => {
293
+ if (!event['text'] || event['text'].length <= 0) return;
294
+ if (event['author'] == 'user') {
295
+ // ユーザーメッセージ
296
+ agent.create_user_message(messages, event['text']);
297
+ } else {
298
+ // エージェントメッセージ
299
+ txt = agent.create_agent_message(messages, cmdbox.random_string(16));
300
+ agent.format_agent_message(container, messages, txt, event['text']);
301
+ }
302
+ });
303
+ });
304
+ });
305
+ return history;
306
+ };
307
+ agent.delete_session = async (session_id) => {
308
+ const formData = new FormData();
309
+ formData.append('session_id', session_id);
310
+ const res = await fetch('agent/session/delete', {method: 'POST', body: formData});
311
+ if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
312
+ return await res.json();
313
+ }
314
+ $(() => {
315
+ // カラーモード対応
316
+ cmdbox.change_color_mode();
317
+ // スプリッター初期化
318
+ $('.split-pane').splitPane();
319
+ // アイコンを表示
320
+ cmdbox.set_logoicon('.navbar-brand');
321
+ // copyright表示
322
+ cmdbox.copyright();
323
+ // バージョン情報モーダル初期化
324
+ cmdbox.init_version_modal();
325
+ // モーダルボタン初期化
326
+ cmdbox.init_modal_button();
327
+ // コマンド実行用のオプション取得
328
+ cmdbox.get_server_opt(true, $('.filer_form')).then(async (opt) => {
329
+ agent.init_form();
330
+ });
331
+ // dropdownメニューを閉じる
332
+ const histories = $('#histories');
333
+ $(document).on('click', (e) => {
334
+ histories.find('.dropdown-menu').hide();
335
+ }).on('contextmenu', (e) => {
336
+ histories.find('.dropdown-menu').hide();
337
+ });
338
+ });