aidp-cli 1.0.0__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.
- aidp_cli/__init__.py +3 -0
- aidp_cli/body_security.py +166 -0
- aidp_cli/discovery.py +34 -0
- aidp_cli/main.py +2006 -0
- aidp_cli/manifest.py +229 -0
- aidp_cli/operation_manifest.json +29073 -0
- aidp_cli-1.0.0.dist-info/METADATA +10 -0
- aidp_cli-1.0.0.dist-info/RECORD +13 -0
- aidp_cli-1.0.0.dist-info/WHEEL +5 -0
- aidp_cli-1.0.0.dist-info/entry_points.txt +2 -0
- aidp_cli-1.0.0.dist-info/licenses/LICENSE.txt +35 -0
- aidp_cli-1.0.0.dist-info/licenses/NOTICE.txt +1 -0
- aidp_cli-1.0.0.dist-info/top_level.txt +1 -0
aidp_cli/manifest.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from importlib import resources
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
MANIFEST_FILENAME = "operation_manifest.json"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class CommandField:
|
|
16
|
+
name: str
|
|
17
|
+
cli_name: str
|
|
18
|
+
original_name: str
|
|
19
|
+
location: str
|
|
20
|
+
required: bool
|
|
21
|
+
description: str = ""
|
|
22
|
+
type_name: str = ""
|
|
23
|
+
model_name: str = ""
|
|
24
|
+
enum_values: tuple[Any, ...] = ()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class BodyField:
|
|
29
|
+
name: str
|
|
30
|
+
required: bool
|
|
31
|
+
type_name: str = ""
|
|
32
|
+
item_type: str = ""
|
|
33
|
+
model_name: str = ""
|
|
34
|
+
enum_values: tuple[Any, ...] = ()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class BodyVariant:
|
|
39
|
+
discriminator_field: str
|
|
40
|
+
discriminator_value: Any
|
|
41
|
+
model_name: str
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class BodyModel:
|
|
46
|
+
name: str
|
|
47
|
+
fields: tuple[BodyField, ...]
|
|
48
|
+
required_fields: tuple[str, ...]
|
|
49
|
+
enum_fields: dict[str, tuple[Any, ...]]
|
|
50
|
+
variants: tuple[BodyVariant, ...] = ()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class CommandDefinition:
|
|
55
|
+
name: str
|
|
56
|
+
sdk_method_name: str
|
|
57
|
+
operation_id: str
|
|
58
|
+
http_method: str
|
|
59
|
+
path: str
|
|
60
|
+
section: str
|
|
61
|
+
summary: str
|
|
62
|
+
description: str
|
|
63
|
+
deprecated: bool
|
|
64
|
+
fields: tuple[CommandField, ...]
|
|
65
|
+
body_field: CommandField | None
|
|
66
|
+
body_model: str
|
|
67
|
+
body_fields: tuple[BodyField, ...]
|
|
68
|
+
body_required_fields: tuple[str, ...]
|
|
69
|
+
body_enum_fields: dict[str, tuple[Any, ...]]
|
|
70
|
+
body_models: dict[str, BodyModel]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class CommandGroup:
|
|
75
|
+
name: str
|
|
76
|
+
tag: str
|
|
77
|
+
client_class_name: str
|
|
78
|
+
description: str
|
|
79
|
+
commands: tuple[CommandDefinition, ...]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass(frozen=True)
|
|
83
|
+
class CommandManifest:
|
|
84
|
+
version: int
|
|
85
|
+
source_spec: str
|
|
86
|
+
source_spec_sha256: str
|
|
87
|
+
command_groups: tuple[CommandGroup, ...]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def load_command_manifest() -> CommandManifest:
|
|
91
|
+
try:
|
|
92
|
+
content = resources.files(__package__).joinpath(MANIFEST_FILENAME).read_text(encoding="utf-8")
|
|
93
|
+
except FileNotFoundError as exc:
|
|
94
|
+
raise RuntimeError(
|
|
95
|
+
"AIDP command manifest is missing. Regenerate the CLI package before running aidp."
|
|
96
|
+
) from exc
|
|
97
|
+
try:
|
|
98
|
+
raw = json.loads(content)
|
|
99
|
+
if not isinstance(raw, dict):
|
|
100
|
+
raise TypeError("manifest root must be a JSON object")
|
|
101
|
+
if not isinstance(raw.get("commandGroups"), list):
|
|
102
|
+
raise TypeError("manifest commandGroups must be a list")
|
|
103
|
+
return manifest_from_dict(raw)
|
|
104
|
+
except (json.JSONDecodeError, KeyError, TypeError, ValueError) as exc:
|
|
105
|
+
raise RuntimeError(
|
|
106
|
+
"AIDP command manifest is invalid. Regenerate the CLI package before running aidp."
|
|
107
|
+
) from exc
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def manifest_from_dict(raw: dict[str, Any]) -> CommandManifest:
|
|
111
|
+
return CommandManifest(
|
|
112
|
+
version=int(raw.get("version", 0)),
|
|
113
|
+
source_spec=str(raw.get("sourceSpec", "")),
|
|
114
|
+
source_spec_sha256=str(raw.get("sourceSpecSha256", "")),
|
|
115
|
+
command_groups=tuple(group_from_dict(group) for group in raw.get("commandGroups", [])),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def group_from_dict(raw: dict[str, Any]) -> CommandGroup:
|
|
120
|
+
return CommandGroup(
|
|
121
|
+
name=str(raw["name"]),
|
|
122
|
+
tag=str(raw.get("tag", "")),
|
|
123
|
+
client_class_name=str(raw["clientClassName"]),
|
|
124
|
+
description=str(raw.get("description", "")),
|
|
125
|
+
commands=tuple(command_from_dict(command) for command in raw.get("commands", [])),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def command_from_dict(raw: dict[str, Any]) -> CommandDefinition:
|
|
130
|
+
fields = tuple(field_from_dict(field) for field in raw.get("fields", []))
|
|
131
|
+
body_field_name = raw.get("bodyField")
|
|
132
|
+
return CommandDefinition(
|
|
133
|
+
name=str(raw["name"]),
|
|
134
|
+
sdk_method_name=str(raw["sdkMethodName"]),
|
|
135
|
+
operation_id=str(raw.get("operationId", "")),
|
|
136
|
+
http_method=str(raw.get("httpMethod", "")),
|
|
137
|
+
path=str(raw.get("path", "")),
|
|
138
|
+
section=str(raw.get("section", "Available Commands")),
|
|
139
|
+
summary=str(raw.get("summary", "")),
|
|
140
|
+
description=str(raw.get("description", "")),
|
|
141
|
+
deprecated=bool(raw.get("deprecated", False)),
|
|
142
|
+
fields=fields,
|
|
143
|
+
body_field=next((field for field in fields if field.name == body_field_name), None),
|
|
144
|
+
body_model=str(raw.get("bodyModel", "")),
|
|
145
|
+
body_fields=tuple(body_field_from_dict(field) for field in raw.get("bodyFields", [])),
|
|
146
|
+
body_required_fields=tuple(str(field) for field in raw.get("bodyRequiredFields", [])),
|
|
147
|
+
body_enum_fields={
|
|
148
|
+
str(name): tuple(values)
|
|
149
|
+
for name, values in raw.get("bodyEnumFields", {}).items()
|
|
150
|
+
},
|
|
151
|
+
body_models={
|
|
152
|
+
str(name): body_model_from_dict(str(name), model)
|
|
153
|
+
for name, model in raw.get("bodyModels", {}).items()
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def field_from_dict(raw: dict[str, Any]) -> CommandField:
|
|
159
|
+
return CommandField(
|
|
160
|
+
name=str(raw["name"]),
|
|
161
|
+
cli_name=str(raw["cliName"]),
|
|
162
|
+
original_name=str(raw.get("originalName", raw["name"])),
|
|
163
|
+
location=str(raw.get("in", "")),
|
|
164
|
+
required=bool(raw.get("required", False)),
|
|
165
|
+
description=str(raw.get("description", "")),
|
|
166
|
+
type_name=str(raw.get("type", "")),
|
|
167
|
+
model_name=str(raw.get("modelName", "")),
|
|
168
|
+
enum_values=tuple(raw.get("enumValues", [])),
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def body_field_from_dict(raw: dict[str, Any]) -> BodyField:
|
|
173
|
+
return BodyField(
|
|
174
|
+
name=str(raw["name"]),
|
|
175
|
+
required=bool(raw.get("required", False)),
|
|
176
|
+
type_name=str(raw.get("type", "")),
|
|
177
|
+
item_type=str(raw.get("itemType", "")),
|
|
178
|
+
model_name=str(raw.get("modelName", "")),
|
|
179
|
+
enum_values=tuple(raw.get("enumValues", [])),
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def body_model_from_dict(name: str, raw: dict[str, Any]) -> BodyModel:
|
|
184
|
+
return BodyModel(
|
|
185
|
+
name=name,
|
|
186
|
+
fields=tuple(body_field_from_dict(field) for field in raw.get("fields", [])),
|
|
187
|
+
required_fields=tuple(str(field) for field in raw.get("requiredFields", [])),
|
|
188
|
+
enum_fields={
|
|
189
|
+
str(field_name): tuple(values)
|
|
190
|
+
for field_name, values in raw.get("enumFields", {}).items()
|
|
191
|
+
},
|
|
192
|
+
variants=tuple(body_variant_from_dict(variant) for variant in raw.get("variants", [])),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def body_variant_from_dict(raw: dict[str, Any]) -> BodyVariant:
|
|
197
|
+
return BodyVariant(
|
|
198
|
+
discriminator_field=str(raw["discriminatorField"]),
|
|
199
|
+
discriminator_value=raw.get("discriminatorValue"),
|
|
200
|
+
model_name=str(raw["modelName"]),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def find_command_group(manifest: CommandManifest, name: str) -> CommandGroup | None:
|
|
205
|
+
normalized = normalize_lookup_name(name)
|
|
206
|
+
return next(
|
|
207
|
+
(
|
|
208
|
+
group
|
|
209
|
+
for group in manifest.command_groups
|
|
210
|
+
if normalize_lookup_name(group.name) == normalized
|
|
211
|
+
),
|
|
212
|
+
None,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def find_command(group: CommandGroup, name: str) -> CommandDefinition | None:
|
|
217
|
+
normalized = normalize_lookup_name(name)
|
|
218
|
+
return next(
|
|
219
|
+
(
|
|
220
|
+
command
|
|
221
|
+
for command in group.commands
|
|
222
|
+
if normalize_lookup_name(command.name) == normalized
|
|
223
|
+
),
|
|
224
|
+
None,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def normalize_lookup_name(value: str) -> str:
|
|
229
|
+
return value.replace("-", "").replace("_", "").lower()
|