licos-platform-cli 0.7.0__tar.gz → 0.8.1__tar.gz
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.
- licos_platform_cli-0.7.0/README.md → licos_platform_cli-0.8.1/PKG-INFO +27 -1
- licos_platform_cli-0.7.0/PKG-INFO → licos_platform_cli-0.8.1/README.md +19 -9
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/pyproject.toml +2 -2
- licos_platform_cli-0.8.1/src/licos_platform_cli/enterprise_project_commands.py +52 -0
- licos_platform_cli-0.8.1/src/licos_platform_cli/enterprise_project_help.py +31 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/help_commands.py +4 -1
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/main.py +2 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/ontology_package_commands.py +19 -5
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/tests/test_cli.py +2 -1
- licos_platform_cli-0.8.1/tests/test_enterprise_projects.py +57 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/tests/test_ontology_packages.py +10 -1
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/.gitignore +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/__init__.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/database_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/identity.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/knowledge_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/oauth_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/ontology_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/project_config_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/storage_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/user_commands.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/tests/test_identity.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/tests/test_project_config.py +0 -0
- {licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/tests/test_user.py +0 -0
|
@@ -1,7 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: licos-platform-cli
|
|
3
|
+
Version: 0.8.1
|
|
4
|
+
Summary: LICOS platform CLI
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: licos-platform-sdk>=0.9.1
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
1
9
|
# licos-platform-cli
|
|
2
10
|
|
|
3
11
|
LICOS 平台命令行工具。`licos-platform help` 返回结构化 JSON 帮助。
|
|
4
12
|
|
|
13
|
+
## 企业项目(0.8.1 起)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
licos-platform help enterprise-projects
|
|
17
|
+
licos-platform enterprise-projects list --all
|
|
18
|
+
licos-platform enterprise-projects search --query 发票 --type AGENT --type AICODING_AGENT --all
|
|
19
|
+
licos-platform enterprise-projects show RECORD_ID
|
|
20
|
+
licos-platform enterprise-projects capability --tenant-id TENANT --workspace-id WORKSPACE --resource-type AICODING_WORKFLOW --resource-id RESOURCE
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
查询包含当前用户可见的在线低代码智能体、AI 编程智能体和 AI 编程工作流;`invocation` 保留关闭调用、未就绪等原因。`--all` 完整读取匹配页;默认一页,可用 `--page`、`--page-size`。精确发布契约使用 `capability --record-id RECORD_ID`,与稳定资源选择互斥。
|
|
24
|
+
|
|
25
|
+
命令只做发现,业务代码查项目实际安装的 SDK 文档后接入。帮助中的 `sdk` 字段提供文档入口;命令身份遵循下文“当前使用者”规则。
|
|
26
|
+
|
|
5
27
|
## 当前使用者(0.5.1 起)
|
|
6
28
|
|
|
7
29
|
```bash
|
|
@@ -10,7 +32,7 @@ licos-platform user me --workspace-id <执行工作空间ID>
|
|
|
10
32
|
licos-platform help user me
|
|
11
33
|
```
|
|
12
34
|
|
|
13
|
-
用户接口默认使用 `LICOS_CURRENT_USER_ID`
|
|
35
|
+
用户接口默认使用 `LICOS_CURRENT_USER_ID` 指定的当前命令用户换取 Token。编程助手执行命令时,由平台根据本次请求注入该标识;独立终端沿用其启动身份,不会自动跟随网页登录者变化。平台地址、服务凭证和项目工作空间沿用运行时配置。
|
|
14
36
|
运行时使用 `AGENT_CURRENT_USER_ID` 注入当前用户时同样支持,不以项目负责人替代当前执行用户。企业和空间上下文沿用平台签发的认证结果。
|
|
15
37
|
多用户请求可将当前使用者 Token 通过标准输入传入,不将 Token 放在命令行参数中:
|
|
16
38
|
|
|
@@ -57,6 +79,10 @@ result = subprocess.run(
|
|
|
57
79
|
|
|
58
80
|
显式传入的 Token 鉴权失败时返回非零退出码,由调用方更新登录凭证,不切换到容器用户或项目所有者。项目所有者和工作空间等资源归属字段单独保留,不用它们冒充调用用户。
|
|
59
81
|
|
|
82
|
+
## 本体正式版本
|
|
83
|
+
|
|
84
|
+
0.8.0 起,`ontology package/bind --root-object-id <id>` 自动选择最新正式版;使用显式 release_id 固定版本。`ontology resolve --configuration-file ontology.json` 解析 `{versionPolicy, rootObjectId, binding}`,省略策略保持固定版本。新运行开始解析并保存输出绑定,query/function 及恢复执行复用它,不在每次查询时重新解析。新版缺少已选对象、属性或函数时直接失败。
|
|
85
|
+
|
|
60
86
|
## 编程项目登录身份
|
|
61
87
|
|
|
62
88
|
- 有内置登录时使用内置登录会话;没有内置登录时使用当前 LICOS 网页登录。内置登录未登录或过期时不能切换成平台用户。
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: licos-platform-cli
|
|
3
|
-
Version: 0.7.0
|
|
4
|
-
Summary: LICOS platform CLI
|
|
5
|
-
Requires-Python: >=3.10
|
|
6
|
-
Requires-Dist: licos-platform-sdk>=0.8.0
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
|
|
9
1
|
# licos-platform-cli
|
|
10
2
|
|
|
11
3
|
LICOS 平台命令行工具。`licos-platform help` 返回结构化 JSON 帮助。
|
|
12
4
|
|
|
5
|
+
## 企业项目(0.8.1 起)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
licos-platform help enterprise-projects
|
|
9
|
+
licos-platform enterprise-projects list --all
|
|
10
|
+
licos-platform enterprise-projects search --query 发票 --type AGENT --type AICODING_AGENT --all
|
|
11
|
+
licos-platform enterprise-projects show RECORD_ID
|
|
12
|
+
licos-platform enterprise-projects capability --tenant-id TENANT --workspace-id WORKSPACE --resource-type AICODING_WORKFLOW --resource-id RESOURCE
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
查询包含当前用户可见的在线低代码智能体、AI 编程智能体和 AI 编程工作流;`invocation` 保留关闭调用、未就绪等原因。`--all` 完整读取匹配页;默认一页,可用 `--page`、`--page-size`。精确发布契约使用 `capability --record-id RECORD_ID`,与稳定资源选择互斥。
|
|
16
|
+
|
|
17
|
+
命令只做发现,业务代码查项目实际安装的 SDK 文档后接入。帮助中的 `sdk` 字段提供文档入口;命令身份遵循下文“当前使用者”规则。
|
|
18
|
+
|
|
13
19
|
## 当前使用者(0.5.1 起)
|
|
14
20
|
|
|
15
21
|
```bash
|
|
@@ -18,7 +24,7 @@ licos-platform user me --workspace-id <执行工作空间ID>
|
|
|
18
24
|
licos-platform help user me
|
|
19
25
|
```
|
|
20
26
|
|
|
21
|
-
用户接口默认使用 `LICOS_CURRENT_USER_ID`
|
|
27
|
+
用户接口默认使用 `LICOS_CURRENT_USER_ID` 指定的当前命令用户换取 Token。编程助手执行命令时,由平台根据本次请求注入该标识;独立终端沿用其启动身份,不会自动跟随网页登录者变化。平台地址、服务凭证和项目工作空间沿用运行时配置。
|
|
22
28
|
运行时使用 `AGENT_CURRENT_USER_ID` 注入当前用户时同样支持,不以项目负责人替代当前执行用户。企业和空间上下文沿用平台签发的认证结果。
|
|
23
29
|
多用户请求可将当前使用者 Token 通过标准输入传入,不将 Token 放在命令行参数中:
|
|
24
30
|
|
|
@@ -65,6 +71,10 @@ result = subprocess.run(
|
|
|
65
71
|
|
|
66
72
|
显式传入的 Token 鉴权失败时返回非零退出码,由调用方更新登录凭证,不切换到容器用户或项目所有者。项目所有者和工作空间等资源归属字段单独保留,不用它们冒充调用用户。
|
|
67
73
|
|
|
74
|
+
## 本体正式版本
|
|
75
|
+
|
|
76
|
+
0.8.0 起,`ontology package/bind --root-object-id <id>` 自动选择最新正式版;使用显式 release_id 固定版本。`ontology resolve --configuration-file ontology.json` 解析 `{versionPolicy, rootObjectId, binding}`,省略策略保持固定版本。新运行开始解析并保存输出绑定,query/function 及恢复执行复用它,不在每次查询时重新解析。新版缺少已选对象、属性或函数时直接失败。
|
|
77
|
+
|
|
68
78
|
## 编程项目登录身份
|
|
69
79
|
|
|
70
80
|
- 有内置登录时使用内置登录会话;没有内置登录时使用当前 LICOS 网页登录。内置登录未登录或过期时不能切换成平台用户。
|
|
@@ -4,12 +4,12 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "licos-platform-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.8.1"
|
|
8
8
|
description = "LICOS platform CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"licos-platform-sdk>=0.
|
|
12
|
+
"licos-platform-sdk>=0.9.1",
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
[project.scripts]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Read-only discovery of published enterprise agents and coding workflows."""
|
|
2
|
+
from licos_platform_sdk import ConfigurationError, enterprise_projects
|
|
3
|
+
|
|
4
|
+
from .identity import add_user_token_option, user_token
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _list(args):
|
|
8
|
+
options = {"query": args.query, "resource_types": args.resource_types,
|
|
9
|
+
"page_size": args.page_size, "user_token": user_token(args)}
|
|
10
|
+
if args.all:
|
|
11
|
+
if args.page != 1:
|
|
12
|
+
raise ConfigurationError("--all starts at page 1; do not combine it with another --page")
|
|
13
|
+
return {"items": list(enterprise_projects.iter_projects(**options))}
|
|
14
|
+
return enterprise_projects.list_projects(page=args.page, **options)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _capability(args):
|
|
18
|
+
token = user_token(args)
|
|
19
|
+
if args.record_id:
|
|
20
|
+
if any((args.tenant_id, args.workspace_id, args.resource_type)):
|
|
21
|
+
raise ConfigurationError("--record-id cannot be combined with resource identity fields")
|
|
22
|
+
return enterprise_projects.capability(args.record_id, user_token=token)
|
|
23
|
+
resource = {"tenant_id": args.tenant_id, "workspace_id": args.workspace_id,
|
|
24
|
+
"resource_type": args.resource_type, "resource_id": args.resource_id}
|
|
25
|
+
return enterprise_projects.current_capability(resource, user_token=token)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def add_enterprise_project_parser(subparsers):
|
|
29
|
+
group = subparsers.add_parser("enterprise-projects", help="Discover visible published enterprise agents and coding workflows")
|
|
30
|
+
commands = group.add_subparsers(dest="enterprise_project_command", required=True)
|
|
31
|
+
for name in ("list", "search"):
|
|
32
|
+
parser = commands.add_parser(name, help="List visible publications, including disabled or unready calls")
|
|
33
|
+
parser.add_argument("--query", required=name == "search", default="", help="Search published name and description")
|
|
34
|
+
parser.add_argument("--type", dest="resource_types", action="append", choices=enterprise_projects.RESOURCE_TYPES)
|
|
35
|
+
parser.add_argument("--page", type=int, default=1)
|
|
36
|
+
parser.add_argument("--page-size", type=int, default=50)
|
|
37
|
+
parser.add_argument("--all", action="store_true", help="Read all matching pages")
|
|
38
|
+
add_user_token_option(parser)
|
|
39
|
+
parser.set_defaults(handler=_list)
|
|
40
|
+
detail = commands.add_parser("show", help="Read a visible online publication and invocation availability")
|
|
41
|
+
detail.add_argument("record_id")
|
|
42
|
+
add_user_token_option(detail)
|
|
43
|
+
detail.set_defaults(handler=lambda args: enterprise_projects.get_project(args.record_id, user_token=user_token(args)))
|
|
44
|
+
capability = commands.add_parser("capability", help="Read the exact publication contract or resolve a stable resource to its current publication")
|
|
45
|
+
selector = capability.add_mutually_exclusive_group(required=True)
|
|
46
|
+
selector.add_argument("--record-id")
|
|
47
|
+
selector.add_argument("--resource-id")
|
|
48
|
+
capability.add_argument("--tenant-id")
|
|
49
|
+
capability.add_argument("--workspace-id")
|
|
50
|
+
capability.add_argument("--resource-type", choices=enterprise_projects.RESOURCE_TYPES)
|
|
51
|
+
add_user_token_option(capability)
|
|
52
|
+
capability.set_defaults(handler=_capability)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
ENTERPRISE_PROJECT_HELP = {
|
|
2
|
+
"topic": "enterprise-projects",
|
|
3
|
+
"description": "查询当前用户可见的在线企业项目:低代码智能体、AI 编程智能体和 AI 编程工作流。",
|
|
4
|
+
"rules": [
|
|
5
|
+
"查询包含关闭调用及尚未就绪的可见项目;invocation 字段说明是否可调用及原因。",
|
|
6
|
+
"用 --all 读取全部匹配页。默认按当前用户查询全部可见范围,不限定当前开发工作空间。",
|
|
7
|
+
"先从列表取得完整 resource,再读取当前 capability 的输入输出 Schema,不按同名项目替换目标。",
|
|
8
|
+
"CLI 用于发现;业务代码查项目实际安装版本的 SDK 文档后接入 project-invocations。",
|
|
9
|
+
"新调用解析当前发布;已有任务恢复沿用原 invocation_id、record_id 和 contract_revision。",
|
|
10
|
+
],
|
|
11
|
+
"sdk": {
|
|
12
|
+
"discovery": "Python licos-platform-sdk 的 enterprise_projects 模块;实际版本 README 的企业项目章节。",
|
|
13
|
+
"invocation": "Python licos-agent-runtime 包内 docs/enterprise-projects.md;先由项目 SDK.md 确认解释器。",
|
|
14
|
+
"locate": "from importlib.resources import files; print(files('licos_agent_runtime').joinpath('docs/enterprise-projects.md').read_text(encoding='utf-8'))",
|
|
15
|
+
},
|
|
16
|
+
"commands": {
|
|
17
|
+
"list": {"description": "读取一页在线可见项目,--all 读取全部页。", "example": "licos-platform enterprise-projects list --all"},
|
|
18
|
+
"search": {"description": "服务端按发布名称和描述搜索。", "example": "licos-platform enterprise-projects search --query 发票 --all"},
|
|
19
|
+
"show": {"description": "查看精确发布记录及调用状态。", "example": "licos-platform enterprise-projects show RECORD_ID"},
|
|
20
|
+
"capability": {"description": "读取精确发布契约,或按完整 resource 解析当前在线发布。",
|
|
21
|
+
"example": "licos-platform enterprise-projects capability --tenant-id TENANT --workspace-id WORKSPACE --resource-type AGENT --resource-id RESOURCE"},
|
|
22
|
+
},
|
|
23
|
+
"parameters": {
|
|
24
|
+
"--type": "list/search 可重复指定 AGENT、AICODING_AGENT、AICODING_WORKFLOW。",
|
|
25
|
+
"--page": "从 1 开始;不能将 --all 与非 1 页组合。",
|
|
26
|
+
"--page-size": "1 到 100,默认 50。",
|
|
27
|
+
"--record-id": "capability 使用精确发布 ID;与资源选择互斥。",
|
|
28
|
+
"--resource-id": "capability 同时需要 --tenant-id、--workspace-id、--resource-type。",
|
|
29
|
+
"--token-stdin": "从 stdin 读取本次用户 Token;省略时使用当前 CLI 用户身份,不使用项目所有者替代。",
|
|
30
|
+
},
|
|
31
|
+
}
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/help_commands.py
RENAMED
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
from typing import Any, Callable
|
|
5
5
|
from .user_commands import USER_HELP
|
|
6
6
|
from .ontology_package_commands import PACKAGE_HELP
|
|
7
|
+
from .enterprise_project_help import ENTERPRISE_PROJECT_HELP
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
Handler = Callable[[argparse.Namespace], Any]
|
|
@@ -799,7 +800,7 @@ ONTOLOGY_HELP = {
|
|
|
799
800
|
"Resolve elements by stable IDs before querying context, model checks, or mapped data.",
|
|
800
801
|
"elementId/objectElementId 是部署实例 ID;objectTypeId 从实例上下文读取,是对象模板 ID。",
|
|
801
802
|
"函数使用目录中的 apiName 和 version,input 满足 inputSchema;objects 传对象导入描述,每组需明确部署实例。动作仍使用列表 id 作为 actionTypeId。",
|
|
802
|
-
"
|
|
803
|
+
"正式应用默认用 ontology package/bind --root-object-id 选择最新正式版;显式 release_id 固定版本。ontology resolve 在新运行开始解析配置,保存绑定供整轮及恢复复用。函数版本仍显式固定,不能调用 CURRENT 或包外函数。",
|
|
803
804
|
"动作预览明确传入 objectElementId 和真实 objectKey;用户确认后用同一草稿的 confirmationId 执行。实例参数必须已在当前工具 schema 中声明,缺失时报告上游目录问题。",
|
|
804
805
|
"READ tools query state, PREPARE tools validate a change draft, and PERSIST tools apply an explicitly confirmed draft.",
|
|
805
806
|
"PERSIST commands require --confirm. Never reuse a catalog result after its catalogVersion changes.",
|
|
@@ -849,6 +850,7 @@ ONTOLOGY_HELP = {
|
|
|
849
850
|
ONTOLOGY_HELP["commands"].update(PACKAGE_HELP)
|
|
850
851
|
|
|
851
852
|
HELP_TOPICS = {
|
|
853
|
+
"enterprise-projects": ENTERPRISE_PROJECT_HELP,
|
|
852
854
|
"user": USER_HELP,
|
|
853
855
|
"storage": STORAGE_HELP,
|
|
854
856
|
"database": DATABASE_HELP,
|
|
@@ -892,6 +894,7 @@ def _cmd_help(args: argparse.Namespace) -> dict[str, Any]:
|
|
|
892
894
|
"licos-platform help ontology",
|
|
893
895
|
"licos-platform help ontology search",
|
|
894
896
|
"licos-platform help user me",
|
|
897
|
+
"licos-platform help enterprise-projects",
|
|
895
898
|
],
|
|
896
899
|
"topics": sorted(HELP_TOPICS),
|
|
897
900
|
}
|
|
@@ -8,6 +8,7 @@ from typing import Any, Sequence
|
|
|
8
8
|
from licos_platform_sdk import PlatformSdkError
|
|
9
9
|
|
|
10
10
|
from .database_commands import add_database_parser
|
|
11
|
+
from .enterprise_project_commands import add_enterprise_project_parser
|
|
11
12
|
from .help_commands import add_help_parser
|
|
12
13
|
from .knowledge_commands import add_knowledge_parser
|
|
13
14
|
from .oauth_commands import add_oauth_parser
|
|
@@ -40,6 +41,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
40
41
|
add_project_config_parser(subparsers)
|
|
41
42
|
add_ontology_parser(subparsers)
|
|
42
43
|
add_user_parser(subparsers)
|
|
44
|
+
add_enterprise_project_parser(subparsers)
|
|
43
45
|
return parser
|
|
44
46
|
|
|
45
47
|
|
|
@@ -11,13 +11,18 @@ from .identity import add_user_token_option, user_token
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
PACKAGE_HELP = {
|
|
14
|
+
"resolve": {"description": "Resolve a latestPublished/pinned selection once at run start. Persist the returned binding for all queries and resume.",
|
|
15
|
+
"parameters": [{"name": "--configuration-file", "required": True, "description": "JSON containing binding, versionPolicy and rootObjectId."}],
|
|
16
|
+
"example": "licos-platform ontology resolve --configuration-file ontology.json"},
|
|
14
17
|
"releases": {"description": "List visible published releases using the current execution identity.", "parameters": [],
|
|
15
18
|
"example": "licos-platform ontology releases"},
|
|
16
19
|
"package": {"description": "Inspect semantic metadata of a specific release; excludes physical mappings and implementation DSL.",
|
|
17
|
-
"parameters": [{"name": "release_id", "required":
|
|
20
|
+
"parameters": [{"name": "release_id", "required": False, "description": "Pinned release; mutually exclusive with --root-object-id."},
|
|
21
|
+
{"name": "--root-object-id", "required": False, "description": "Inspect the latest formally published release of this ontology root."}],
|
|
18
22
|
"example": "licos-platform ontology package <release_id>"},
|
|
19
23
|
"bind": {"description": "Create a binding JSON for a published release; save the output in trusted application configuration.",
|
|
20
|
-
"parameters": [{"name": "release_id", "required":
|
|
24
|
+
"parameters": [{"name": "release_id", "required": False, "description": "Pinned release; mutually exclusive with --root-object-id."},
|
|
25
|
+
{"name": "--root-object-id", "required": False, "description": "Resolve latest formally published model once for this run."},
|
|
21
26
|
{"name": "--objects-file", "required": True, "description": "JSON array of elementId and attributeIds selections."},
|
|
22
27
|
{"name": "--functions-file", "required": False, "description": "JSON array of apiName/version selections. Omitted selects no functions."}],
|
|
23
28
|
"example": "licos-platform ontology bind <release_id> --objects-file objects.json --functions-file functions.json"},
|
|
@@ -83,10 +88,14 @@ def _run(args: argparse.Namespace) -> Any:
|
|
|
83
88
|
if operation == "releases":
|
|
84
89
|
return ontology.list_releases(user_token=token)
|
|
85
90
|
if operation == "package":
|
|
86
|
-
return ontology.
|
|
91
|
+
return (ontology.get_latest_package(args.root_object_id, user_token=token) if args.root_object_id
|
|
92
|
+
else ontology.get_package(args.release_id, user_token=token))
|
|
87
93
|
if operation == "bind":
|
|
88
|
-
|
|
94
|
+
bind = ontology.create_latest_binding if args.root_object_id else ontology.create_binding
|
|
95
|
+
return bind(args.root_object_id or args.release_id, _file(args.objects_file),
|
|
89
96
|
_file(args.functions_file) if args.functions_file else [], user_token=token)
|
|
97
|
+
if operation == "resolve":
|
|
98
|
+
return ontology.resolve_binding(_file(args.configuration_file), user_token=token)
|
|
90
99
|
if operation == "diff":
|
|
91
100
|
before = ontology.get_package(args.before, user_token=token)
|
|
92
101
|
after = ontology.get_package(args.after, user_token=token)
|
|
@@ -105,6 +114,7 @@ def add_package_commands(commands: argparse._SubParsersAction) -> None:
|
|
|
105
114
|
("releases", "List visible published ontology releases"),
|
|
106
115
|
("package", "Inspect semantic metadata of one release"),
|
|
107
116
|
("bind", "Create an explicit release and capability binding"),
|
|
117
|
+
("resolve", "Resolve a saved version policy once at run start"),
|
|
108
118
|
("validate", "Verify a binding against its published artifact"),
|
|
109
119
|
("query", "Query business objects within a binding"),
|
|
110
120
|
("function", "Invoke a versioned read-only function within a binding"),
|
|
@@ -114,7 +124,11 @@ def add_package_commands(commands: argparse._SubParsersAction) -> None:
|
|
|
114
124
|
add_user_token_option(parser)
|
|
115
125
|
parser.set_defaults(handler=_run)
|
|
116
126
|
if name in {"package", "bind"}:
|
|
117
|
-
parser.
|
|
127
|
+
selection = parser.add_mutually_exclusive_group(required=True)
|
|
128
|
+
selection.add_argument("release_id", nargs="?")
|
|
129
|
+
selection.add_argument("--root-object-id", help="Use the latest formally published release of this stable ontology root")
|
|
130
|
+
if name == "resolve":
|
|
131
|
+
parser.add_argument("--configuration-file", required=True)
|
|
118
132
|
if name in {"validate", "query", "function"}:
|
|
119
133
|
parser.add_argument("--binding-file", required=True)
|
|
120
134
|
if name == "bind":
|
|
@@ -84,6 +84,7 @@ class PlatformCliTests(unittest.TestCase):
|
|
|
84
84
|
payload["topics"],
|
|
85
85
|
[
|
|
86
86
|
"database",
|
|
87
|
+
"enterprise-projects",
|
|
87
88
|
"knowledge",
|
|
88
89
|
"oauth",
|
|
89
90
|
"ontology",
|
|
@@ -136,7 +137,7 @@ class PlatformCliTests(unittest.TestCase):
|
|
|
136
137
|
self.assertEqual(stderr, "")
|
|
137
138
|
payload = json.loads(stdout)
|
|
138
139
|
self.assertEqual(payload["topic"], "ontology")
|
|
139
|
-
self.assertEqual(set(payload["commands"]), {"search", "invoke", "releases", "package", "bind", "validate", "query", "function", "diff"})
|
|
140
|
+
self.assertEqual(set(payload["commands"]), {"search", "invoke", "releases", "package", "bind", "resolve", "validate", "query", "function", "diff"})
|
|
140
141
|
self.assertTrue(any("catalogVersion" in rule for rule in payload["rules"]))
|
|
141
142
|
sdk_help = "\n".join(payload["sdk"].values())
|
|
142
143
|
self.assertNotIn("items[0]", sdk_help)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import unittest
|
|
5
|
+
from contextlib import redirect_stderr, redirect_stdout
|
|
6
|
+
from unittest.mock import patch
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
10
|
+
from licos_platform_cli.main import main
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run(*args):
|
|
14
|
+
out, err = io.StringIO(), io.StringIO()
|
|
15
|
+
with redirect_stdout(out), redirect_stderr(err):
|
|
16
|
+
try:
|
|
17
|
+
status = main(list(args))
|
|
18
|
+
except SystemExit as error:
|
|
19
|
+
status = error.code
|
|
20
|
+
return status, out.getvalue(), err.getvalue()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EnterpriseProjectCommandTests(unittest.TestCase):
|
|
24
|
+
def test_cli_current_user_reaches_real_sdk_with_search_and_type(self):
|
|
25
|
+
response = httpx.Response(200, request=httpx.Request("GET", "https://platform.test/catalog"),
|
|
26
|
+
json={"code": 0, "data": {"records": [], "total": 0, "current": 1, "size": 50, "pages": 0}})
|
|
27
|
+
with patch.dict(os.environ, {"LICOS_CURRENT_USER_ID": "caller", "LICOS_USER_ID": "owner",
|
|
28
|
+
"LICOS_PLATFORM_API_BASE_URL": "https://platform.test"}, clear=True), \
|
|
29
|
+
patch("licos_platform_cli.identity.runtime_user_token", return_value="caller-token") as exchange, \
|
|
30
|
+
patch.object(httpx, "get", return_value=response) as get:
|
|
31
|
+
status, output, _ = run("enterprise-projects", "search", "--query", "发票", "--type", "AICODING_WORKFLOW", "--all")
|
|
32
|
+
self.assertEqual(status, 0)
|
|
33
|
+
self.assertEqual(json.loads(output), {"items": []})
|
|
34
|
+
exchange.assert_called_once_with("caller")
|
|
35
|
+
self.assertEqual(get.call_args.kwargs["params"]["resourceTypes"], "AICODING_WORKFLOW")
|
|
36
|
+
self.assertEqual(get.call_args.kwargs["headers"]["Authorization"], "Bearer caller-token")
|
|
37
|
+
|
|
38
|
+
def test_explicit_request_token_does_not_exchange_owner_identity(self):
|
|
39
|
+
with patch("sys.stdin", io.StringIO("request-token")), \
|
|
40
|
+
patch("licos_platform_cli.identity.runtime_user_token") as exchange, \
|
|
41
|
+
patch("licos_platform_cli.enterprise_project_commands.enterprise_projects.capability", return_value={"record_id": "record"}) as call:
|
|
42
|
+
status, _, _ = run("enterprise-projects", "capability", "--record-id", "record", "--token-stdin")
|
|
43
|
+
self.assertEqual(status, 0)
|
|
44
|
+
exchange.assert_not_called()
|
|
45
|
+
call.assert_called_once_with("record", user_token="request-token")
|
|
46
|
+
|
|
47
|
+
def test_help_explains_discovery_and_sdk_document_entry(self):
|
|
48
|
+
status, output, _ = run("help", "enterprise-projects")
|
|
49
|
+
self.assertEqual(status, 0)
|
|
50
|
+
value = json.loads(output)
|
|
51
|
+
self.assertIn("enterprise-projects.md", value["sdk"]["invocation"])
|
|
52
|
+
self.assertEqual(set(value["commands"]), {"list", "search", "show", "capability"})
|
|
53
|
+
|
|
54
|
+
def test_lowcode_workflow_and_incomplete_identity_fail(self):
|
|
55
|
+
self.assertEqual(run("enterprise-projects", "list", "--type", "WORKFLOW")[0], 2)
|
|
56
|
+
with patch("sys.stdin", io.StringIO("caller")):
|
|
57
|
+
self.assertEqual(run("enterprise-projects", "capability", "--resource-id", "id", "--token-stdin")[0], 1)
|
|
@@ -16,7 +16,7 @@ from test_cli import run_cli
|
|
|
16
16
|
|
|
17
17
|
class OntologyPackageCliTests(unittest.TestCase):
|
|
18
18
|
def test_package_commands_have_structured_help(self):
|
|
19
|
-
for command in ("releases", "package", "bind", "validate", "query", "function", "diff"):
|
|
19
|
+
for command in ("releases", "package", "bind", "resolve", "validate", "query", "function", "diff"):
|
|
20
20
|
code, output, error = run_cli("help", "ontology", command)
|
|
21
21
|
self.assertEqual((code, error), (0, ""))
|
|
22
22
|
self.assertIn("parameters", json.loads(output))
|
|
@@ -26,6 +26,15 @@ class OntologyPackageCliTests(unittest.TestCase):
|
|
|
26
26
|
identity.start()
|
|
27
27
|
self.addCleanup(identity.stop)
|
|
28
28
|
|
|
29
|
+
@patch("licos_platform_cli.identity.runtime_user_token", return_value="caller-token")
|
|
30
|
+
@patch("licos_platform_cli.ontology_package_commands.ontology.get_latest_package", return_value={"version": "V2"})
|
|
31
|
+
def test_latest_package_selects_by_root_and_rejects_ambiguous_input(self, latest, _identity):
|
|
32
|
+
code, _, error = run_cli("ontology", "package", "--root-object-id", "root-1")
|
|
33
|
+
self.assertEqual((code, error), (0, ""))
|
|
34
|
+
latest.assert_called_once_with("root-1", user_token="caller-token")
|
|
35
|
+
code, _, _ = run_cli("ontology", "package", "release-1", "--root-object-id", "root-1")
|
|
36
|
+
self.assertNotEqual(code, 0)
|
|
37
|
+
|
|
29
38
|
@patch("licos_platform_cli.identity.runtime_user_token", return_value="caller-token")
|
|
30
39
|
@patch("licos_platform_cli.ontology_package_commands.ontology.list_releases", return_value=[])
|
|
31
40
|
def test_releases_forwards_runtime_identity(self, releases, _identity):
|
|
File without changes
|
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/database_commands.py
RENAMED
|
File without changes
|
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/knowledge_commands.py
RENAMED
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/oauth_commands.py
RENAMED
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/ontology_commands.py
RENAMED
|
File without changes
|
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/storage_commands.py
RENAMED
|
File without changes
|
{licos_platform_cli-0.7.0 → licos_platform_cli-0.8.1}/src/licos_platform_cli/user_commands.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|