cmdbox 0.6.3.1__py3-none-any.whl → 0.6.4__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 (135) hide show
  1. cmdbox/app/app.py +16 -7
  2. cmdbox/app/common.py +2 -2
  3. cmdbox/app/commons/loghandler.py +4 -1
  4. cmdbox/app/commons/redis_client.py +1 -1
  5. cmdbox/app/edge.py +1 -1
  6. cmdbox/app/feature.py +1 -1
  7. cmdbox/app/features/cli/cmdbox_audit_createdb.py +224 -224
  8. cmdbox/app/features/cli/cmdbox_audit_delete.py +4 -4
  9. cmdbox/app/features/cli/cmdbox_audit_search.py +4 -4
  10. cmdbox/app/features/cli/cmdbox_audit_write.py +6 -8
  11. cmdbox/app/features/cli/cmdbox_client_file_copy.py +3 -3
  12. cmdbox/app/features/cli/cmdbox_client_file_download.py +3 -3
  13. cmdbox/app/features/cli/cmdbox_client_file_list.py +3 -3
  14. cmdbox/app/features/cli/cmdbox_client_file_mkdir.py +3 -3
  15. cmdbox/app/features/cli/cmdbox_client_file_move.py +3 -3
  16. cmdbox/app/features/cli/cmdbox_client_file_remove.py +3 -3
  17. cmdbox/app/features/cli/cmdbox_client_file_rmdir.py +3 -3
  18. cmdbox/app/features/cli/cmdbox_client_file_upload.py +3 -3
  19. cmdbox/app/features/cli/cmdbox_client_http.py +7 -6
  20. cmdbox/app/features/cli/cmdbox_client_server_info.py +4 -4
  21. cmdbox/app/features/cli/cmdbox_cmd_list.py +3 -3
  22. cmdbox/app/features/cli/cmdbox_cmd_load.py +5 -5
  23. cmdbox/app/features/cli/cmdbox_edge_config.py +1 -1
  24. cmdbox/app/features/cli/cmdbox_edge_start.py +3 -3
  25. cmdbox/app/features/cli/cmdbox_mcp_client.py +174 -174
  26. cmdbox/app/features/cli/cmdbox_mcp_proxy.py +96 -96
  27. cmdbox/app/features/cli/cmdbox_server_list.py +2 -2
  28. cmdbox/app/features/cli/cmdbox_server_start.py +103 -103
  29. cmdbox/app/features/cli/cmdbox_server_stop.py +4 -4
  30. cmdbox/app/features/cli/cmdbox_tts_install.py +307 -0
  31. cmdbox/app/features/cli/cmdbox_tts_say.py +179 -0
  32. cmdbox/app/features/cli/cmdbox_tts_start.py +329 -0
  33. cmdbox/app/features/cli/cmdbox_tts_stop.py +108 -0
  34. cmdbox/app/features/cli/cmdbox_web_apikey_add.py +91 -106
  35. cmdbox/app/features/cli/cmdbox_web_apikey_del.py +91 -106
  36. cmdbox/app/features/cli/cmdbox_web_gencert.py +6 -6
  37. cmdbox/app/features/cli/cmdbox_web_genpass.py +168 -168
  38. cmdbox/app/features/cli/cmdbox_web_group_add.py +94 -109
  39. cmdbox/app/features/cli/cmdbox_web_group_del.py +87 -102
  40. cmdbox/app/features/cli/cmdbox_web_group_edit.py +94 -109
  41. cmdbox/app/features/cli/cmdbox_web_group_list.py +87 -102
  42. cmdbox/app/features/cli/cmdbox_web_start.py +235 -235
  43. cmdbox/app/features/cli/cmdbox_web_stop.py +72 -72
  44. cmdbox/app/features/cli/cmdbox_web_user_add.py +104 -119
  45. cmdbox/app/features/cli/cmdbox_web_user_del.py +87 -102
  46. cmdbox/app/features/cli/cmdbox_web_user_edit.py +104 -119
  47. cmdbox/app/features/cli/cmdbox_web_user_list.py +87 -102
  48. cmdbox/app/filer.py +9 -9
  49. cmdbox/app/mcp.py +15 -7
  50. cmdbox/app/options.py +46 -43
  51. cmdbox/app/server.py +224 -224
  52. cmdbox/app/web.py +1 -1
  53. cmdbox/extensions/features.yml +3 -0
  54. cmdbox/extensions/sample_project/sample/app/features/cli/sample_client_time.py +2 -2
  55. cmdbox/extensions/sample_project/sample/app/features/cli/sample_server_time.py +3 -3
  56. cmdbox/licenses/LICENSE_Werkzeug_3_1_1_BSD_License.txt +28 -0
  57. cmdbox/licenses/LICENSE_absolufy-imports_0_3_1_MIT_License.txt +21 -0
  58. cmdbox/licenses/LICENSE_cyclopts_3_22_5_Apache_Software_License.txt +201 -0
  59. cmdbox/licenses/LICENSE_isodate_0_7_2_BSD_License.txt +26 -0
  60. cmdbox/licenses/LICENSE_lazy-object-proxy_1_11_0_BSD_License.txt +20 -0
  61. cmdbox/licenses/LICENSE_openapi-core_0_19_5_BSD_License.txt +29 -0
  62. cmdbox/licenses/LICENSE_openapi-schema-validator_0_6_3_BSD_License.txt +29 -0
  63. cmdbox/licenses/LICENSE_openapi-spec-validator_0_7_2_Apache_Software_License.txt +201 -0
  64. cmdbox/licenses/LICENSE_opentelemetry-semantic-conventions_0_57b0_UNKNOWN.txt +201 -0
  65. cmdbox/licenses/LICENSE_parse_1_20_2_MIT_License.txt +19 -0
  66. cmdbox/licenses/LICENSE_pathable_0_4_4_Apache_Software_License.txt +201 -0
  67. cmdbox/licenses/{LICENSE_pillow_11_2_1_UNKNOWN.txt → LICENSE_pillow_11_3_0_UNKNOWN.txt} +393 -3
  68. cmdbox/licenses/LICENSE_pyperclip_1_9_0_BSD_License.txt +27 -0
  69. cmdbox/licenses/LICENSE_rfc3339-validator_0_1_4_MIT_License.txt +22 -0
  70. cmdbox/licenses/LICENSE_rich-rst_1_3_1_MIT_License.txt +7 -0
  71. cmdbox/licenses/{LICENSE_setuptools_65_5_0_MIT_License.txt → LICENSE_setuptools_80_9_0_UNKNOWN.txt} +0 -2
  72. cmdbox/licenses/LICENSE_tokenizers_0_21_4_Apache_Software_License.txt +1 -0
  73. cmdbox/licenses/LICENSE_voicevox_core_0_16_0_MIT.txt +20 -0
  74. cmdbox/licenses/LICENSE_watchdog_6_0_0_Apache_Software_License.txt +16 -0
  75. cmdbox/licenses/{LICENSE_typer_0_16_0_MIT_License.txt → LICENSE_wsproto_1_2_0_MIT_License.txt} +2 -2
  76. cmdbox/licenses/files.txt +56 -42
  77. cmdbox/logconf_cmdbox.yml +104 -0
  78. cmdbox/version.py +2 -2
  79. cmdbox/web/agent.html +8 -2
  80. cmdbox/web/assets/cmdbox/agent.js +182 -1
  81. cmdbox/web/assets/cmdbox/common.js +16 -3
  82. cmdbox/web/assets/cmdbox/svgicon.js +18 -0
  83. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info}/METADATA +28 -20
  84. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info}/RECORD +124 -114
  85. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info}/WHEEL +1 -1
  86. cmdbox/config.yml +0 -3
  87. cmdbox/licenses/LICENSE_httptools_0_6_4_MIT_License.txt +0 -21
  88. cmdbox/licenses/LICENSE_shellingham_1_5_4_ISC_License-ISCL.txt +0 -13
  89. cmdbox/licenses/LICENSE_watchfiles_1_1_0_MIT_License.txt +0 -21
  90. cmdbox/logconf_audit.yml +0 -43
  91. cmdbox/logconf_client.yml +0 -43
  92. cmdbox/logconf_edge.yml +0 -43
  93. cmdbox/logconf_gui.yml +0 -43
  94. cmdbox/logconf_mcp.yml +0 -43
  95. cmdbox/logconf_server.yml +0 -43
  96. cmdbox/logconf_web.yml +0 -43
  97. /cmdbox/licenses/{LICENSE_Authlib_1_6_0_BSD_License.txt → LICENSE_Authlib_1_6_1_BSD_License.txt} +0 -0
  98. /cmdbox/licenses/{LICENSE_SQLAlchemy_2_0_41_MIT.txt → LICENSE_SQLAlchemy_2_0_42_MIT.txt} +0 -0
  99. /cmdbox/licenses/{LICENSE_aiohttp_3_12_13_Apache-2_0.txt → LICENSE_aiohttp_3_12_15_Apache-2_0_AND_MIT.txt} +0 -0
  100. /cmdbox/licenses/{LICENSE_aiosignal_1_3_2_Apache_Software_License.txt → LICENSE_aiosignal_1_4_0_Apache_Software_License.txt} +0 -0
  101. /cmdbox/licenses/{LICENSE_certifi_2025_6_15_Mozilla_Public_License_2_0-MPL_2_0.txt → LICENSE_certifi_2025_7_14_Mozilla_Public_License_2_0-MPL_2_0.txt} +0 -0
  102. /cmdbox/licenses/{LICENSE_cryptography_45_0_4_Apache-2_0_OR_BSD-3-Clause.txt → LICENSE_cryptography_45_0_5_Apache-2_0_OR_BSD-3-Clause.txt} +0 -0
  103. /cmdbox/licenses/{LICENSE_docstring_parser_0_16_MIT_License.txt → LICENSE_docstring_parser_0_17_0_MIT_License.txt} +0 -0
  104. /cmdbox/licenses/{LICENSE_fastapi_0_115_14_MIT_License.txt → LICENSE_fastapi_0_116_1_MIT_License.txt} +0 -0
  105. /cmdbox/licenses/{LICENSE_fastmcp_2_10_1_Apache_Software_License.txt → LICENSE_fastmcp_2_11_0_Apache_Software_License.txt} +0 -0
  106. /cmdbox/licenses/{LICENSE_fsspec_2025_5_1_BSD_License.txt → LICENSE_fsspec_2025_7_0_BSD_License.txt} +0 -0
  107. /cmdbox/licenses/{LICENSE_google-adk_1_5_0_Apache_Software_License.txt → LICENSE_google-adk_1_9_0_Apache_Software_License.txt} +0 -0
  108. /cmdbox/licenses/{LICENSE_google-api-python-client_2_174_0_Apache_Software_License.txt → LICENSE_google-api-python-client_2_177_0_Apache_Software_License.txt} +0 -0
  109. /cmdbox/licenses/{LICENSE_google-cloud-aiplatform_1_100_0_Apache_2_0.txt → LICENSE_google-cloud-aiplatform_1_106_0_Apache_2_0.txt} +0 -0
  110. /cmdbox/licenses/{LICENSE_google-cloud-bigquery_3_34_0_Apache_Software_License.txt → LICENSE_google-cloud-bigquery_3_35_1_Apache_Software_License.txt} +0 -0
  111. /cmdbox/licenses/{LICENSE_google-genai_1_23_0_Apache_Software_License.txt → LICENSE_google-genai_1_28_0_Apache_Software_License.txt} +0 -0
  112. /cmdbox/licenses/{LICENSE_grpcio-status_1_73_1_Apache_Software_License.txt → LICENSE_grpcio-status_1_74_0_Apache_Software_License.txt} +0 -0
  113. /cmdbox/licenses/{LICENSE_grpcio_1_73_1_Apache_Software_License.txt → LICENSE_grpcio_1_74_0_Apache_Software_License.txt} +0 -0
  114. /cmdbox/licenses/{LICENSE_huggingface-hub_0_33_1_Apache_Software_License.txt → LICENSE_huggingface-hub_0_34_3_Apache_Software_License.txt} +0 -0
  115. /cmdbox/licenses/{LICENSE_opentelemetry-api_1_34_1_Apache_Software_License.txt → LICENSE_jsonschema-path_0_3_4_Apache_Software_License.txt} +0 -0
  116. /cmdbox/licenses/{LICENSE_jsonschema_4_24_0_UNKNOWN.txt → LICENSE_jsonschema_4_25_0_UNKNOWN.txt} +0 -0
  117. /cmdbox/licenses/{LICENSE_litellm_1_73_6_MIT_License.txt → LICENSE_litellm_1_74_12_MIT_License.txt} +0 -0
  118. /cmdbox/licenses/{LICENSE_mcp_1_10_1_MIT_License.txt → LICENSE_mcp_1_12_3_MIT_License.txt} +0 -0
  119. /cmdbox/licenses/{LICENSE_multidict_6_6_2_Apache_License_2_0.txt → LICENSE_multidict_6_6_3_Apache_License_2_0.txt} +0 -0
  120. /cmdbox/licenses/{LICENSE_nh3_0_2_21_MIT.txt → LICENSE_nh3_0_3_0_MIT.txt} +0 -0
  121. /cmdbox/licenses/{LICENSE_numpy_2_3_1_BSD_License.txt → LICENSE_numpy_2_3_2_BSD_License.txt} +0 -0
  122. /cmdbox/licenses/{LICENSE_openai_1_93_0_Apache_Software_License.txt → LICENSE_openai_1_98_0_Apache_Software_License.txt} +0 -0
  123. /cmdbox/licenses/{LICENSE_opentelemetry-sdk_1_34_1_Apache_Software_License.txt → LICENSE_opentelemetry-api_1_36_0_UNKNOWN.txt} +0 -0
  124. /cmdbox/licenses/{LICENSE_opentelemetry-semantic-conventions_0_55b1_Apache_Software_License.txt → LICENSE_opentelemetry-sdk_1_36_0_UNKNOWN.txt} +0 -0
  125. /cmdbox/licenses/{LICENSE_tokenizers_0_21_2_Apache_Software_License.txt → LICENSE_pywin32_311_Python_Software_Foundation_License.txt} +0 -0
  126. /cmdbox/licenses/{LICENSE_regex_2024_11_6_Apache_Software_License.txt → LICENSE_regex_2025_7_34_UNKNOWN.txt} +0 -0
  127. /cmdbox/licenses/{LICENSE_rich_14_0_0_MIT_License.txt → LICENSE_rich_14_1_0_MIT_License.txt} +0 -0
  128. /cmdbox/licenses/{LICENSE_rpds-py_0_25_1_MIT.txt → LICENSE_rpds-py_0_26_0_MIT.txt} +0 -0
  129. /cmdbox/licenses/{LICENSE_sse-starlette_2_3_6_BSD_License.txt → LICENSE_sse-starlette_3_0_2_UNKNOWN.txt} +0 -0
  130. /cmdbox/licenses/{LICENSE_starlette_0_46_2_BSD_License.txt → LICENSE_starlette_0_47_2_BSD_License.txt} +0 -0
  131. /cmdbox/licenses/{LICENSE_typing_extensions_4_14_0_UNKNOWN.txt → LICENSE_typing_extensions_4_14_1_UNKNOWN.txt} +0 -0
  132. /cmdbox/licenses/{LICENSE_zope_event_5_1_Zope_Public_License.txt → LICENSE_zope_event_5_1_1_Zope_Public_License.txt} +0 -0
  133. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info}/entry_points.txt +0 -0
  134. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info/licenses}/LICENSE +0 -0
  135. {cmdbox-0.6.3.1.dist-info → cmdbox-0.6.4.dist-info}/top_level.txt +0 -0
@@ -1,119 +1,104 @@
1
- from cmdbox.app import common, feature, web
2
- from cmdbox.app.options import Options
3
- from pathlib import Path
4
- from typing import Dict, Any, Tuple, List, Union
5
- import argparse
6
- import logging
7
-
8
-
9
- class WebUserEdit(feature.UnsupportEdgeFeature):
10
- def get_mode(self) -> Union[str, List[str]]:
11
- """
12
- この機能のモードを返します
13
-
14
- Returns:
15
- Union[str, List[str]]: モード
16
- """
17
- return 'web'
18
-
19
- def get_cmd(self):
20
- """
21
- この機能のコマンドを返します
22
-
23
- Returns:
24
- str: コマンド
25
- """
26
- return 'user_edit'
27
-
28
- def get_option(self):
29
- """
30
- この機能のオプションを返します
31
-
32
- Returns:
33
- Dict[str, Any]: オプション
34
- """
35
- return dict(
36
- use_redis=self.USE_REDIS_MEIGHT, nouse_webmode=False,
37
- description_ja="Webモードのユーザーを編集します。",
38
- description_en="Edit users in Web mode.",
39
- choice=[
40
- dict(opt="host", type=Options.T_STR, default=self.default_host, required=True, multi=False, hide=True, choice=None, web="mask",
41
- description_ja="Redisサーバーのサービスホストを指定します。",
42
- description_en="Specify the service host of the Redis server."),
43
- dict(opt="port", type=Options.T_INT, default=self.default_port, required=True, multi=False, hide=True, choice=None, web="mask",
44
- description_ja="Redisサーバーのサービスポートを指定します。",
45
- description_en="Specify the service port of the Redis server."),
46
- dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
- description_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
- description_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
- description_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
- description_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
- dict(opt="data", type=Options.T_DIR, default=self.default_data, required=False, multi=False, hide=False, choice=None,
53
- description_ja=f"省略した時は `$HONE/.{self.ver.__appid__}` を使用します。",
54
- description_en=f"When omitted, `$HONE/.{self.ver.__appid__}` is used."),
55
- dict(opt="user_id", type=Options.T_INT, default=None, required=True, multi=False, hide=False, choice=None,
56
- description_ja="ユーザーIDを指定します。",
57
- description_en="Specify the user ID."),
58
- dict(opt="user_name", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=None,
59
- description_ja="ユーザー名を指定します。他のユーザーと重複しないようにしてください。",
60
- description_en="Specify a user name. Do not duplicate other users."),
61
- dict(opt="user_pass", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
62
- description_ja="ユーザーパスワードを指定します。",
63
- description_en="Specify the user password."),
64
- dict(opt="user_pass_hash", type=Options.T_STR, default='sha1', required=False, multi=False, hide=False, choice=['oauth2', 'saml', 'plain', 'md5', 'sha1', 'sha256'],
65
- description_ja="ユーザーパスワードのハッシュアルゴリズムを指定します。",
66
- description_en="Specifies the hash algorithm for user passwords."),
67
- dict(opt="user_email", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
68
- description_ja="ユーザーメールアドレスを指定します。 `user_pass_hash` が `oauth2` 又は `saml` の時は必須です。",
69
- description_en="Specify the user email. Required when `user_pass_hash` is `oauth2` or `saml`."),
70
- dict(opt="user_group", type=Options.T_STR, default=None, required=True, multi=True, hide=False, choice=None,
71
- description_ja="ユーザーが所属するグループを指定します。",
72
- description_en="Specifies the groups to which the user belongs."),
73
- dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None, fileio="in",
74
- description_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
75
- description_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
76
- dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
77
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をConsole logに出力します。",
78
- description_en="Available only in GUI mode. Outputs standard output during command execution to Console log."),
79
- dict(opt="capture_stdout", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
80
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をキャプチャーし、実行結果画面に表示します。",
81
- description_en="Available only in GUI mode. Captures standard output during command execution and displays it on the execution result screen."),
82
- dict(opt="capture_maxsize", type=Options.T_INT, default=self.DEFAULT_CAPTURE_MAXSIZE, required=False, multi=False, hide=True, choice=None,
83
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力の最大キャプチャーサイズを指定します。",
84
- description_en="Available only in GUI mode. Specifies the maximum capture size of standard output when executing commands."),
85
- ]
86
- )
87
-
88
- def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
89
- """
90
- この機能の実行を行います
91
-
92
- Args:
93
- logger (logging.Logger): ロガー
94
- args (argparse.Namespace): 引数
95
- tm (float): 実行開始時間
96
- pf (List[Dict[str, float]]): 呼出元のパフォーマンス情報
97
-
98
- Returns:
99
- Tuple[int, Dict[str, Any], Any]: 終了コード, 結果, オブジェクト
100
- """
101
- if args.data is None:
102
- msg = dict(warn=f"Please specify the --data option.")
103
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
104
- return 1, msg, None
105
- w = None
106
- try:
107
- w = web.Web(logger, Path(args.data), appcls=self.appcls, ver=self.ver,
108
- redis_host=args.host, redis_port=args.port, redis_password=args.password, svname=args.svname,
109
- signin_file=args.signin_file)
110
- user = dict(uid=args.user_id, name=args.user_name, password=args.user_pass, hash=args.user_pass_hash,
111
- email=args.user_email, groups=args.user_group)
112
- w.user_edit(user)
113
- msg = dict(success=f"User ID {args.user_id} has been edited.")
114
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
115
- return 0, msg, w
116
- except Exception as e:
117
- msg = dict(warn=f"{e}")
118
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
119
- return 1, msg, w
1
+ from cmdbox.app import common, feature, web
2
+ from cmdbox.app.options import Options
3
+ from pathlib import Path
4
+ from typing import Dict, Any, Tuple, List, Union
5
+ import argparse
6
+ import logging
7
+
8
+
9
+ class WebUserEdit(feature.UnsupportEdgeFeature):
10
+ def get_mode(self) -> Union[str, List[str]]:
11
+ """
12
+ この機能のモードを返します
13
+
14
+ Returns:
15
+ Union[str, List[str]]: モード
16
+ """
17
+ return 'web'
18
+
19
+ def get_cmd(self):
20
+ """
21
+ この機能のコマンドを返します
22
+
23
+ Returns:
24
+ str: コマンド
25
+ """
26
+ return 'user_edit'
27
+
28
+ def get_option(self):
29
+ """
30
+ この機能のオプションを返します
31
+
32
+ Returns:
33
+ Dict[str, Any]: オプション
34
+ """
35
+ return dict(
36
+ use_redis=self.USE_REDIS_MEIGHT, nouse_webmode=False,
37
+ description_ja="Webモードのユーザーを編集します。",
38
+ description_en="Edit users in Web mode.",
39
+ choice=[
40
+ dict(opt="user_id", type=Options.T_INT, default=None, required=True, multi=False, hide=False, choice=None,
41
+ description_ja="ユーザーIDを指定します。",
42
+ description_en="Specify the user ID."),
43
+ dict(opt="user_name", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=None,
44
+ description_ja="ユーザー名を指定します。他のユーザーと重複しないようにしてください。",
45
+ description_en="Specify a user name. Do not duplicate other users."),
46
+ dict(opt="user_pass", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
47
+ description_ja="ユーザーパスワードを指定します。",
48
+ description_en="Specify the user password."),
49
+ dict(opt="user_pass_hash", type=Options.T_STR, default='sha1', required=False, multi=False, hide=False, choice=['oauth2', 'saml', 'plain', 'md5', 'sha1', 'sha256'],
50
+ description_ja="ユーザーパスワードのハッシュアルゴリズムを指定します。",
51
+ description_en="Specifies the hash algorithm for user passwords."),
52
+ dict(opt="user_email", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
53
+ description_ja="ユーザーメールアドレスを指定します。 `user_pass_hash` が `oauth2` 又は `saml` の時は必須です。",
54
+ description_en="Specify the user email. Required when `user_pass_hash` is `oauth2` or `saml`."),
55
+ dict(opt="user_group", type=Options.T_STR, default=None, required=True, multi=True, hide=False, choice=None,
56
+ description_ja="ユーザーが所属するグループを指定します。",
57
+ description_en="Specifies the groups to which the user belongs."),
58
+ dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None, fileio="in",
59
+ description_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
60
+ description_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
61
+ dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
62
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をConsole logに出力します。",
63
+ description_en="Available only in GUI mode. Outputs standard output during command execution to Console log."),
64
+ dict(opt="capture_stdout", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
65
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をキャプチャーし、実行結果画面に表示します。",
66
+ description_en="Available only in GUI mode. Captures standard output during command execution and displays it on the execution result screen."),
67
+ dict(opt="capture_maxsize", type=Options.T_INT, default=self.DEFAULT_CAPTURE_MAXSIZE, required=False, multi=False, hide=True, choice=None,
68
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力の最大キャプチャーサイズを指定します。",
69
+ description_en="Available only in GUI mode. Specifies the maximum capture size of standard output when executing commands."),
70
+ ]
71
+ )
72
+
73
+ def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
74
+ """
75
+ この機能の実行を行います
76
+
77
+ Args:
78
+ logger (logging.Logger): ロガー
79
+ args (argparse.Namespace): 引数
80
+ tm (float): 実行開始時間
81
+ pf (List[Dict[str, float]]): 呼出元のパフォーマンス情報
82
+
83
+ Returns:
84
+ Tuple[int, Dict[str, Any], Any]: 終了コード, 結果, オブジェクト
85
+ """
86
+ if args.data is None:
87
+ msg = dict(warn=f"Please specify the --data option.")
88
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
89
+ return self.RESP_WARN, msg, None
90
+ w = None
91
+ try:
92
+ w = web.Web(logger, self.default_data, appcls=self.appcls, ver=self.ver,
93
+ redis_host=self.default_host, redis_port=self.default_port, redis_password=self.default_pass, svname=self.default_svname,
94
+ signin_file=args.signin_file)
95
+ user = dict(uid=args.user_id, name=args.user_name, password=args.user_pass, hash=args.user_pass_hash,
96
+ email=args.user_email, groups=args.user_group)
97
+ w.user_edit(user)
98
+ msg = dict(success=f"User ID {args.user_id} has been edited.")
99
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
100
+ return self.RESP_SUCCESS, msg, w
101
+ except Exception as e:
102
+ msg = dict(warn=f"{e}")
103
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
104
+ return self.RESP_WARN, msg, w
@@ -1,102 +1,87 @@
1
- from cmdbox.app import common, feature, web
2
- from cmdbox.app.options import Options
3
- from pathlib import Path
4
- from typing import Dict, Any, Tuple, List, Union
5
- import argparse
6
- import logging
7
-
8
-
9
- class WebUserList(feature.OneshotResultEdgeFeature):
10
- def get_mode(self) -> Union[str, List[str]]:
11
- """
12
- この機能のモードを返します
13
-
14
- Returns:
15
- Union[str, List[str]]: モード
16
- """
17
- return 'web'
18
-
19
- def get_cmd(self):
20
- """
21
- この機能のコマンドを返します
22
-
23
- Returns:
24
- str: コマンド
25
- """
26
- return 'user_list'
27
-
28
- def get_option(self):
29
- """
30
- この機能のオプションを返します
31
-
32
- Returns:
33
- Dict[str, Any]: オプション
34
- """
35
- return dict(
36
- use_redis=self.USE_REDIS_MEIGHT, nouse_webmode=False,
37
- description_ja="Webモードのユーザー一覧を取得します。",
38
- description_en="Get a list of users in Web mode.",
39
- choice=[
40
- dict(opt="host", type=Options.T_STR, default=self.default_host, required=True, multi=False, hide=True, choice=None, web="mask",
41
- description_ja="Redisサーバーのサービスホストを指定します。",
42
- description_en="Specify the service host of the Redis server."),
43
- dict(opt="port", type=Options.T_INT, default=self.default_port, required=True, multi=False, hide=True, choice=None, web="mask",
44
- description_ja="Redisサーバーのサービスポートを指定します。",
45
- description_en="Specify the service port of the Redis server."),
46
- dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
- description_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
- description_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
- description_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
- description_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
- dict(opt="data", type=Options.T_DIR, default=self.default_data, required=False, multi=False, hide=False, choice=None,
53
- description_ja=f"省略した時は `$HONE/.{self.ver.__appid__}` を使用します。",
54
- description_en=f"When omitted, `$HONE/.{self.ver.__appid__}` is used."),
55
- dict(opt="user_name", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
56
- description_ja="ユーザー名を指定して取得します。省略した時は全てのユーザーを取得します。",
57
- description_en="Retrieved by specifying a user name. If omitted, all users are retrieved."),
58
- dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None, fileio="in",
59
- description_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
60
- description_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
61
- dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
62
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をConsole logに出力します。",
63
- description_en="Available only in GUI mode. Outputs standard output during command execution to Console log."),
64
- dict(opt="capture_stdout", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
65
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をキャプチャーし、実行結果画面に表示します。",
66
- description_en="Available only in GUI mode. Captures standard output during command execution and displays it on the execution result screen."),
67
- dict(opt="capture_maxsize", type=Options.T_INT, default=self.DEFAULT_CAPTURE_MAXSIZE, required=False, multi=False, hide=True, choice=None,
68
- description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力の最大キャプチャーサイズを指定します。",
69
- description_en="Available only in GUI mode. Specifies the maximum capture size of standard output when executing commands."),
70
- ]
71
- )
72
-
73
- def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
74
- """
75
- この機能の実行を行います
76
-
77
- Args:
78
- logger (logging.Logger): ロガー
79
- args (argparse.Namespace): 引数
80
- tm (float): 実行開始時間
81
- pf (List[Dict[str, float]]): 呼出元のパフォーマンス情報
82
-
83
- Returns:
84
- Tuple[int, Dict[str, Any], Any]: 終了コード, 結果, オブジェクト
85
- """
86
- if args.data is None:
87
- msg = dict(warn=f"Please specify the --data option.")
88
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
89
- return 1, msg, None
90
- w = None
91
- try:
92
- w = web.Web(logger, Path(args.data), appcls=self.appcls, ver=self.ver,
93
- redis_host=args.host, redis_port=args.port, redis_password=args.password, svname=args.svname,
94
- signin_file=args.signin_file)
95
- users = w.user_list(args.user_name)
96
- msg = dict(success=users)
97
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
98
- return 0, msg, w
99
- except Exception as e:
100
- msg = dict(warn=f"{e}")
101
- common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
102
- return 1, msg, w
1
+ from cmdbox.app import common, feature, web
2
+ from cmdbox.app.options import Options
3
+ from pathlib import Path
4
+ from typing import Dict, Any, Tuple, List, Union
5
+ import argparse
6
+ import logging
7
+
8
+
9
+ class WebUserList(feature.OneshotResultEdgeFeature):
10
+ def get_mode(self) -> Union[str, List[str]]:
11
+ """
12
+ この機能のモードを返します
13
+
14
+ Returns:
15
+ Union[str, List[str]]: モード
16
+ """
17
+ return 'web'
18
+
19
+ def get_cmd(self):
20
+ """
21
+ この機能のコマンドを返します
22
+
23
+ Returns:
24
+ str: コマンド
25
+ """
26
+ return 'user_list'
27
+
28
+ def get_option(self):
29
+ """
30
+ この機能のオプションを返します
31
+
32
+ Returns:
33
+ Dict[str, Any]: オプション
34
+ """
35
+ return dict(
36
+ use_redis=self.USE_REDIS_MEIGHT, nouse_webmode=False,
37
+ description_ja="Webモードのユーザー一覧を取得します。",
38
+ description_en="Get a list of users in Web mode.",
39
+ choice=[
40
+ dict(opt="user_name", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
41
+ description_ja="ユーザー名を指定して取得します。省略した時は全てのユーザーを取得します。",
42
+ description_en="Retrieved by specifying a user name. If omitted, all users are retrieved."),
43
+ dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None, fileio="in",
44
+ description_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
45
+ description_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
46
+ dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
47
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をConsole logに出力します。",
48
+ description_en="Available only in GUI mode. Outputs standard output during command execution to Console log."),
49
+ dict(opt="capture_stdout", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
50
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力をキャプチャーし、実行結果画面に表示します。",
51
+ description_en="Available only in GUI mode. Captures standard output during command execution and displays it on the execution result screen."),
52
+ dict(opt="capture_maxsize", type=Options.T_INT, default=self.DEFAULT_CAPTURE_MAXSIZE, required=False, multi=False, hide=True, choice=None,
53
+ description_ja="GUIモードでのみ使用可能です。コマンド実行時の標準出力の最大キャプチャーサイズを指定します。",
54
+ description_en="Available only in GUI mode. Specifies the maximum capture size of standard output when executing commands."),
55
+ ]
56
+ )
57
+
58
+ def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
59
+ """
60
+ この機能の実行を行います
61
+
62
+ Args:
63
+ logger (logging.Logger): ロガー
64
+ args (argparse.Namespace): 引数
65
+ tm (float): 実行開始時間
66
+ pf (List[Dict[str, float]]): 呼出元のパフォーマンス情報
67
+
68
+ Returns:
69
+ Tuple[int, Dict[str, Any], Any]: 終了コード, 結果, オブジェクト
70
+ """
71
+ if args.data is None:
72
+ msg = dict(warn=f"Please specify the --data option.")
73
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
74
+ return self.RESP_WARN, msg, None
75
+ w = None
76
+ try:
77
+ w = web.Web(logger, self.default_data, appcls=self.appcls, ver=self.ver,
78
+ redis_host=self.default_host, redis_port=self.default_port, redis_password=self.default_pass, svname=self.default_svname,
79
+ signin_file=args.signin_file)
80
+ users = w.user_list(args.user_name)
81
+ msg = dict(success=users)
82
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
83
+ return self.RESP_SUCCESS, msg, w
84
+ except Exception as e:
85
+ msg = dict(warn=f"{e}")
86
+ common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
87
+ return self.RESP_WARN, msg, w
cmdbox/app/filer.py CHANGED
@@ -8,7 +8,7 @@ import mimetypes
8
8
  import shutil
9
9
 
10
10
  class Filer(object):
11
- RESP_SCCESS:int = 0
11
+ RESP_SUCCESS:int = 0
12
12
  RESP_WARN:int = 1
13
13
  RESP_ERROR:int = 2
14
14
  def __init__(self, data_dir: Path, logger: logging.Logger,):
@@ -132,7 +132,7 @@ class Filer(object):
132
132
  file_list:Path = self.data_dir / cpath
133
133
  tpath_key, pt = _path_tree(file_list, cpart, i, recursive if i+1==len(current_path_parts) else False)
134
134
  path_tree[tpath_key] = pt
135
- return self.RESP_SCCESS, dict(success=path_tree)
135
+ return self.RESP_SUCCESS, dict(success=path_tree)
136
136
 
137
137
  def file_mkdir(self, current_path:str) -> Tuple[int, Dict[str, Any]]:
138
138
  """
@@ -152,7 +152,7 @@ class Filer(object):
152
152
  try:
153
153
  abspath.mkdir(parents=True)
154
154
  ret_path = str(Path(current_path).parent).replace("\\","/")
155
- return self.RESP_SCCESS, dict(success=dict(path=f"{ret_path}",msg=f"Created {abspath}"))
155
+ return self.RESP_SUCCESS, dict(success=dict(path=f"{ret_path}",msg=f"Created {abspath}"))
156
156
  except Exception as e:
157
157
  self.logger.warning(f"Failed to create {abspath}. {e}")
158
158
  return self.RESP_WARN, dict(warn=f"Failed to create {abspath}. {e}")
@@ -178,7 +178,7 @@ class Filer(object):
178
178
  try:
179
179
  common.rmdirs(abspath, ignore_errors=False)
180
180
  ret_path = str(Path(current_path).parent).replace("\\","/")
181
- return self.RESP_SCCESS, dict(success=dict(path=f"{ret_path}",msg=f"Removed {abspath}"))
181
+ return self.RESP_SUCCESS, dict(success=dict(path=f"{ret_path}",msg=f"Removed {abspath}"))
182
182
  except Exception as e:
183
183
  self.logger.warning(f"Failed to remove {abspath}. {e}")
184
184
  return self.RESP_WARN, dict(warn=f"Failed to remove {abspath}. {e}")
@@ -213,7 +213,7 @@ class Filer(object):
213
213
  fd = convert.img2byte(img, "jpeg")
214
214
  fname = f"{fname}.thumbnail.jpg"
215
215
  data = convert.bytes2b64str(fd)
216
- return self.RESP_SCCESS, dict(success=dict(name=fname, data=data, mime_type=mime_type))
216
+ return self.RESP_SUCCESS, dict(success=dict(name=fname, data=data, mime_type=mime_type))
217
217
  except Exception as e:
218
218
  self.logger.warning(f"Failed to download {abspath}. {e}")
219
219
  return self.RESP_WARN, dict(warn=f"Failed to download {abspath}. {e}")
@@ -254,7 +254,7 @@ class Filer(object):
254
254
  save_path.parent.mkdir(parents=True, exist_ok=True)
255
255
  with open(save_path, "wb") as f:
256
256
  f.write(file_data)
257
- return self.RESP_SCCESS, dict(success=f"Uploaded {save_path}")
257
+ return self.RESP_SUCCESS, dict(success=f"Uploaded {save_path}")
258
258
  except Exception as e:
259
259
  self.logger.warning(f"Failed to upload {save_path}. {e}")
260
260
  return self.RESP_WARN, dict(warn=f"Failed to upload {save_path}. {e}")
@@ -280,7 +280,7 @@ class Filer(object):
280
280
  try:
281
281
  abspath.unlink()
282
282
  ret_path = str(Path(current_path).parent).replace("\\","/")
283
- return self.RESP_SCCESS, dict(success=dict(path=ret_path, msg=f"Removed {abspath}"))
283
+ return self.RESP_SUCCESS, dict(success=dict(path=ret_path, msg=f"Removed {abspath}"))
284
284
  except Exception as e:
285
285
  self.logger.warning(f"Failed to remove {abspath}. {e}")
286
286
  return self.RESP_WARN, dict(warn=f"Failed to remove {abspath}. {e}")
@@ -316,7 +316,7 @@ class Filer(object):
316
316
  self.logger.warning(f"Path {from_abspath} is not file or directory.")
317
317
  return self.RESP_WARN, dict(warn=f"Path {from_abspath} is not file or directory.")
318
318
 
319
- return self.RESP_SCCESS, dict(success=dict(path=Path(to_path).parent,
319
+ return self.RESP_SUCCESS, dict(success=dict(path=Path(to_path).parent,
320
320
  to_path=to_path,
321
321
  from_path=from_path,
322
322
  ret_path=ret_path,
@@ -344,7 +344,7 @@ class Filer(object):
344
344
 
345
345
  ret_path = shutil.move(from_abspath, to_abspath)
346
346
 
347
- return self.RESP_SCCESS, dict(success=dict(path=Path(to_path).parent,
347
+ return self.RESP_SUCCESS, dict(success=dict(path=Path(to_path).parent,
348
348
  to_path=to_path,
349
349
  from_path=from_path,
350
350
  ret_path=ret_path,
cmdbox/app/mcp.py CHANGED
@@ -49,21 +49,21 @@ class Mcp:
49
49
  Any: FastMCP
50
50
  """
51
51
  from fastmcp import FastMCP
52
- from fastmcp.server.auth import BearerAuthProvider
52
+ from fastmcp.server.auth.providers.jwt import JWTVerifier
53
53
  cls = self.signin.__class__
54
54
  publickey_str = cls.verify_jwt_publickey_str if hasattr(cls, 'verify_jwt_publickey_str') else None
55
55
  issuer = cls.verify_jwt_issuer if hasattr(cls, 'verify_jwt_issuer') else None
56
56
  audience = cls.verify_jwt_audience if hasattr(cls, 'verify_jwt_audience') else None
57
57
  if publickey_str is not None and issuer is not None and audience is not None:
58
- self.logger.info(f"Using BearerAuthProvider with public key, issuer: {issuer}, audience: {audience}")
59
- auth = BearerAuthProvider(
58
+ self.logger.info(f"Using JWTVerifier with public key, issuer: {issuer}, audience: {audience}")
59
+ auth = JWTVerifier(
60
60
  public_key=publickey_str,
61
61
  issuer=issuer,
62
62
  audience=audience
63
63
  )
64
64
  mcp = FastMCP(name=self.ver.__appid__, auth=auth, tools=tools)
65
65
  else:
66
- self.logger.info(f"Using BearerAuthProvider without public key, issuer, or audience.")
66
+ self.logger.info(f"Using JWTVerifier without public key, issuer, or audience.")
67
67
  mcp = FastMCP(name=self.ver.__appid__)
68
68
  mcp.add_middleware(self.create_mw_logging(self.logger, args))
69
69
  mcp.add_middleware(self.create_mw_reqscope(self.logger, args))
@@ -328,6 +328,9 @@ class Mcp:
328
328
  func_txt += f' Dict[str, Any]: 実行結果\n'
329
329
  func_txt += f' """\n'
330
330
  func_txt += f' logger = logging.getLogger("web")\n'
331
+ func_txt += f' if not options.get_cmd_attr("'+mode+'", "'+cmd+'", "use_agent"):\n'
332
+ func_txt += f' logger.warning("{func_name} is not allowed to be executed by the system.")\n'
333
+ func_txt += f' return dict(warn="{func_name} is not allowed to be executed by the system.")\n'
331
334
  func_txt += ' opt = {o["opt"]: kwargs.get(o["opt"], o["default"]) for o in options.get_cmd_choices("'+mode+'", "'+cmd+'", False)}\n'
332
335
  func_txt += f' opt["data"] = Path(opt["data"]) if hasattr(opt, "data") else common.HOME_DIR / f".{self.ver.__appid__}"\n'
333
336
  func_txt += f' if "{title}":\n'
@@ -379,7 +382,7 @@ class Mcp:
379
382
  Returns:
380
383
  ToolList: ToolListのリスト
381
384
  """
382
- tool_list = ToolList(self, logger)
385
+ tool_list = ToolList(self, logger, self.data)
383
386
  tool_list.extract_callable = extract_callable
384
387
  return tool_list
385
388
 
@@ -461,13 +464,14 @@ class Mcp:
461
464
  return runner, mcp
462
465
 
463
466
  class ToolList(object):
464
- def __init__(self, mcp:Mcp, logger:logging.Logger, *args:List):
467
+ def __init__(self, mcp:Mcp, logger:logging.Logger, data:Path, *args:List):
465
468
  """
466
469
  ツールリストを初期化します
467
470
 
468
471
  Args:
469
472
  mcp (Mcp): MCPインスタンス
470
473
  logger (logging.Logger): ロガー
474
+ data (Path): データパス
471
475
  *args (List): 追加するツールのリスト
472
476
  """
473
477
  from fastmcp.tools import FunctionTool
@@ -477,6 +481,7 @@ class ToolList(object):
477
481
  self.tools = []
478
482
  self.mcp = mcp
479
483
  self.logger = logger
484
+ self.data = data
480
485
  self.extract_callable = False
481
486
  for mode in options.get_mode_keys():
482
487
  for cmd in options.get_cmd_keys(mode):
@@ -602,7 +607,7 @@ class ToolList(object):
602
607
  options = Options.getInstance()
603
608
  is_japan = common.is_japan()
604
609
  ret_tools = self.tools.copy()
605
- web = Web.getInstance()
610
+ web = Web.getInstance(self.logger, self.data)
606
611
  if web.signin.signin_file_data is None:
607
612
  # サインインファイルが読み込まれていない場合は登録済みのリストを返す
608
613
  if self.extract_callable:
@@ -633,6 +638,9 @@ class ToolList(object):
633
638
  for opt in cmd_list:
634
639
  func_name = opt['title']
635
640
  mode, cmd, description = opt['mode'], opt['cmd'], opt['description'] if 'description' in opt and opt['description'] else ''
641
+ # ユーザーコマンドもfeatures.ymlの定義に従って実行許可するかどうか。
642
+ #if not options.get_cmd_attr(mode, cmd, 'use_agent'):
643
+ # continue
636
644
  choices = options.get_cmd_choices(mode, cmd, False)
637
645
  description += '\n' + options.get_cmd_attr(mode, cmd, 'description_ja' if is_japan else 'description_en')
638
646
  # 関数の定義を生成