keboola-cli 0.63.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.
- keboola_agent_cli/__init__.py +34 -0
- keboola_agent_cli/__main__.py +5 -0
- keboola_agent_cli/_ui_dist/assets/arc-DhFYIddx.js +2 -0
- keboola_agent_cli/_ui_dist/assets/arc-DhFYIddx.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/architecture-7EHR7CIX-hNCijx_H.js +1 -0
- keboola_agent_cli/_ui_dist/assets/architectureDiagram-3BPJPVTR-C6hUlprM.js +37 -0
- keboola_agent_cli/_ui_dist/assets/architectureDiagram-3BPJPVTR-C6hUlprM.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/array-BifhSqXX.js +2 -0
- keboola_agent_cli/_ui_dist/assets/array-BifhSqXX.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/blockDiagram-GPEHLZMM-DC7qY9i4.js +133 -0
- keboola_agent_cli/_ui_dist/assets/blockDiagram-GPEHLZMM-DC7qY9i4.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/c4Diagram-AAUBKEIU-5Lh44evt.js +11 -0
- keboola_agent_cli/_ui_dist/assets/c4Diagram-AAUBKEIU-5Lh44evt.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/channel-DBMrXlxx.js +2 -0
- keboola_agent_cli/_ui_dist/assets/channel-DBMrXlxx.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-2J33WTMH-Coy82EBh.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-2J33WTMH-Coy82EBh.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-3OPIFGDE-BQC5CRHI.js +63 -0
- keboola_agent_cli/_ui_dist/assets/chunk-3OPIFGDE-BQC5CRHI.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-4BX2VUAB-DUuEt70o.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-4BX2VUAB-DUuEt70o.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-55IACEB6-BvR-6chF.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-55IACEB6-BvR-6chF.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-5ZQYHXKU-BjcTN7ul.js +3 -0
- keboola_agent_cli/_ui_dist/assets/chunk-5ZQYHXKU-BjcTN7ul.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-727SXJPM-C0zxqqRN.js +207 -0
- keboola_agent_cli/_ui_dist/assets/chunk-727SXJPM-C0zxqqRN.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-AQP2D5EJ-CXf7rIlZ.js +232 -0
- keboola_agent_cli/_ui_dist/assets/chunk-AQP2D5EJ-CXf7rIlZ.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-BSJP7CBP-Oj_FO9Q7.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-BSJP7CBP-Oj_FO9Q7.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-CSCIHK7Q-CcTsLrFc.js +124 -0
- keboola_agent_cli/_ui_dist/assets/chunk-CSCIHK7Q-CcTsLrFc.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-FMBD7UC4-FH-zLkkW.js +16 -0
- keboola_agent_cli/_ui_dist/assets/chunk-FMBD7UC4-FH-zLkkW.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-L5ZTLDWV-B1Ky_e7O.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-L5ZTLDWV-B1Ky_e7O.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-ND2GUHAM-BHz1rpbm.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-ND2GUHAM-BHz1rpbm.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-NNHCCRGN-DlpIbxXb.js +160 -0
- keboola_agent_cli/_ui_dist/assets/chunk-NNHCCRGN-DlpIbxXb.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-NZK2D7GU-tnrSoegS.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-NZK2D7GU-tnrSoegS.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-O5CBEL6O-DxxqDH0l.js +71 -0
- keboola_agent_cli/_ui_dist/assets/chunk-O5CBEL6O-DxxqDH0l.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/chunk-QZHKN3VN-CSjc2gjj.js +2 -0
- keboola_agent_cli/_ui_dist/assets/chunk-QZHKN3VN-CSjc2gjj.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/classDiagram-4FO5ZUOK-BuZcZu85.js +2 -0
- keboola_agent_cli/_ui_dist/assets/classDiagram-4FO5ZUOK-BuZcZu85.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/classDiagram-v2-Q7XG4LA2-BuZcZu85.js +2 -0
- keboola_agent_cli/_ui_dist/assets/classDiagram-v2-Q7XG4LA2-BuZcZu85.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/cose-bilkent-S5V4N54A-Y0L8LDMa.js +2 -0
- keboola_agent_cli/_ui_dist/assets/cose-bilkent-S5V4N54A-Y0L8LDMa.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/cytoscape.esm-C8YCVR3_.js +322 -0
- keboola_agent_cli/_ui_dist/assets/cytoscape.esm-C8YCVR3_.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/dagre-BM42HDAG-UZ-9BTqF.js +5 -0
- keboola_agent_cli/_ui_dist/assets/dagre-BM42HDAG-UZ-9BTqF.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/dagre-Bx709z4p.js +2 -0
- keboola_agent_cli/_ui_dist/assets/dagre-Bx709z4p.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/defaultLocale-C8Fc0cco.js +2 -0
- keboola_agent_cli/_ui_dist/assets/defaultLocale-C8Fc0cco.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/diagram-2AECGRRQ-DoDQ60wi.js +44 -0
- keboola_agent_cli/_ui_dist/assets/diagram-2AECGRRQ-DoDQ60wi.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/diagram-5GNKFQAL-CMGFxpUs.js +11 -0
- keboola_agent_cli/_ui_dist/assets/diagram-5GNKFQAL-CMGFxpUs.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/diagram-KO2AKTUF-1uGDa-Iu.js +4 -0
- keboola_agent_cli/_ui_dist/assets/diagram-KO2AKTUF-1uGDa-Iu.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/diagram-LMA3HP47-XtFH7B51.js +25 -0
- keboola_agent_cli/_ui_dist/assets/diagram-LMA3HP47-XtFH7B51.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/diagram-OG6HWLK6-B4_Te1T5.js +25 -0
- keboola_agent_cli/_ui_dist/assets/diagram-OG6HWLK6-B4_Te1T5.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/dist-Di6zmlv0.js +2 -0
- keboola_agent_cli/_ui_dist/assets/dist-Di6zmlv0.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/erDiagram-TEJ5UH35-NjQkrdFt.js +86 -0
- keboola_agent_cli/_ui_dist/assets/erDiagram-TEJ5UH35-NjQkrdFt.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/eventmodeling-FCH6USID-BrJMIks8.js +1 -0
- keboola_agent_cli/_ui_dist/assets/flowDiagram-I6XJVG4X-CIr8DWl7.js +163 -0
- keboola_agent_cli/_ui_dist/assets/flowDiagram-I6XJVG4X-CIr8DWl7.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/ganttDiagram-6RSMTGT7-C1VY_xbQ.js +293 -0
- keboola_agent_cli/_ui_dist/assets/ganttDiagram-6RSMTGT7-C1VY_xbQ.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/gitGraph-WXDBUCRP-COacYjo-.js +1 -0
- keboola_agent_cli/_ui_dist/assets/gitGraphDiagram-PVQCEYII-DQT8-kg2.js +107 -0
- keboola_agent_cli/_ui_dist/assets/gitGraphDiagram-PVQCEYII-DQT8-kg2.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/graphlib-B8gBHxth.js +2 -0
- keboola_agent_cli/_ui_dist/assets/graphlib-B8gBHxth.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/index-CMq50kkV.css +1 -0
- keboola_agent_cli/_ui_dist/assets/index-D8W97DAz.js +118 -0
- keboola_agent_cli/_ui_dist/assets/index-D8W97DAz.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/info-J43DQDTF-DdCTRIzU.js +1 -0
- keboola_agent_cli/_ui_dist/assets/infoDiagram-5YYISTIA-C77rsoTp.js +3 -0
- keboola_agent_cli/_ui_dist/assets/infoDiagram-5YYISTIA-C77rsoTp.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/init-D6jRqBbL.js +2 -0
- keboola_agent_cli/_ui_dist/assets/init-D6jRqBbL.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/ishikawaDiagram-YF4QCWOH-BcTbXaLy.js +71 -0
- keboola_agent_cli/_ui_dist/assets/ishikawaDiagram-YF4QCWOH-BcTbXaLy.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/journeyDiagram-JHISSGLW-BejeAJQ_.js +140 -0
- keboola_agent_cli/_ui_dist/assets/journeyDiagram-JHISSGLW-BejeAJQ_.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/kanban-definition-UN3LZRKU-BRNz_UrH.js +90 -0
- keboola_agent_cli/_ui_dist/assets/kanban-definition-UN3LZRKU-BRNz_UrH.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/katex-C4eR7coU.js +258 -0
- keboola_agent_cli/_ui_dist/assets/katex-C4eR7coU.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/line-CzAQKFbJ.js +2 -0
- keboola_agent_cli/_ui_dist/assets/line-CzAQKFbJ.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/linear-DUNFFdck.js +2 -0
- keboola_agent_cli/_ui_dist/assets/linear-DUNFFdck.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/mermaid-parser.core-CpuBOkFa.js +5 -0
- keboola_agent_cli/_ui_dist/assets/mermaid-parser.core-CpuBOkFa.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/mindmap-definition-RKZ34NQL-9EJQNjH0.js +97 -0
- keboola_agent_cli/_ui_dist/assets/mindmap-definition-RKZ34NQL-9EJQNjH0.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/ordinal-hYBb2elL.js +2 -0
- keboola_agent_cli/_ui_dist/assets/ordinal-hYBb2elL.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/packet-YPE3B663-DLiiw_B2.js +1 -0
- keboola_agent_cli/_ui_dist/assets/path-BWPyau1x.js +2 -0
- keboola_agent_cli/_ui_dist/assets/path-BWPyau1x.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/pie-LRSECV5Y-CRoO8G1g.js +1 -0
- keboola_agent_cli/_ui_dist/assets/pieDiagram-4H26LBE5-XH4cy6Cb.js +31 -0
- keboola_agent_cli/_ui_dist/assets/pieDiagram-4H26LBE5-XH4cy6Cb.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/quadrantDiagram-W4KKPZXB-fdhc93U8.js +8 -0
- keboola_agent_cli/_ui_dist/assets/quadrantDiagram-W4KKPZXB-fdhc93U8.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/radar-GUYGQ44K-DAlLVJHm.js +1 -0
- keboola_agent_cli/_ui_dist/assets/requirementDiagram-4Y6WPE33-a94eP3R9.js +85 -0
- keboola_agent_cli/_ui_dist/assets/requirementDiagram-4Y6WPE33-a94eP3R9.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/rough.esm-CSKSodPl.js +2 -0
- keboola_agent_cli/_ui_dist/assets/rough.esm-CSKSodPl.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/sankeyDiagram-5OEKKPKP-jcBa02sp.js +41 -0
- keboola_agent_cli/_ui_dist/assets/sankeyDiagram-5OEKKPKP-jcBa02sp.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/sequenceDiagram-3UESZ5HK-A5-GGM-e.js +163 -0
- keboola_agent_cli/_ui_dist/assets/sequenceDiagram-3UESZ5HK-A5-GGM-e.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/src-ZI-V_AF0.js +2 -0
- keboola_agent_cli/_ui_dist/assets/src-ZI-V_AF0.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/stateDiagram-AJRCARHV-BKAA5rqE.js +2 -0
- keboola_agent_cli/_ui_dist/assets/stateDiagram-AJRCARHV-BKAA5rqE.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/stateDiagram-v2-BHNVJYJU-DnJwJBsE.js +2 -0
- keboola_agent_cli/_ui_dist/assets/stateDiagram-v2-BHNVJYJU-DnJwJBsE.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/timeline-definition-PNZ67QCA-Cy39jp8b.js +121 -0
- keboola_agent_cli/_ui_dist/assets/timeline-definition-PNZ67QCA-Cy39jp8b.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/treeView-BLDUP644-DbLYl23-.js +1 -0
- keboola_agent_cli/_ui_dist/assets/treemap-LRROVOQU-Bp0eGlOt.js +1 -0
- keboola_agent_cli/_ui_dist/assets/vennDiagram-CIIHVFJN-BGECKubd.js +35 -0
- keboola_agent_cli/_ui_dist/assets/vennDiagram-CIIHVFJN-BGECKubd.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/wardley-L42UT6IY-D4yH4jqS.js +1 -0
- keboola_agent_cli/_ui_dist/assets/wardleyDiagram-YWT4CUSO-D6XRG3cZ.js +79 -0
- keboola_agent_cli/_ui_dist/assets/wardleyDiagram-YWT4CUSO-D6XRG3cZ.js.map +1 -0
- keboola_agent_cli/_ui_dist/assets/xychartDiagram-2RQKCTM6-DRre-pfZ.js +8 -0
- keboola_agent_cli/_ui_dist/assets/xychartDiagram-2RQKCTM6-DRre-pfZ.js.map +1 -0
- keboola_agent_cli/_ui_dist/index.html +50 -0
- keboola_agent_cli/ai_client.py +83 -0
- keboola_agent_cli/auto_update.py +550 -0
- keboola_agent_cli/changelog.py +1198 -0
- keboola_agent_cli/cli.py +448 -0
- keboola_agent_cli/client.py +3422 -0
- keboola_agent_cli/commands/__init__.py +0 -0
- keboola_agent_cli/commands/_data_app_git.py +343 -0
- keboola_agent_cli/commands/_helpers.py +377 -0
- keboola_agent_cli/commands/_metadata_input.py +49 -0
- keboola_agent_cli/commands/_semantic_layer_crud.py +632 -0
- keboola_agent_cli/commands/_semantic_layer_helpers.py +44 -0
- keboola_agent_cli/commands/_semantic_layer_reference_data.py +247 -0
- keboola_agent_cli/commands/agent.py +968 -0
- keboola_agent_cli/commands/branch.py +423 -0
- keboola_agent_cli/commands/changelog.py +168 -0
- keboola_agent_cli/commands/component.py +216 -0
- keboola_agent_cli/commands/config.py +2442 -0
- keboola_agent_cli/commands/context.py +1481 -0
- keboola_agent_cli/commands/data_app.py +1279 -0
- keboola_agent_cli/commands/dev_portal.py +584 -0
- keboola_agent_cli/commands/doctor.py +37 -0
- keboola_agent_cli/commands/encrypt.py +145 -0
- keboola_agent_cli/commands/feature.py +311 -0
- keboola_agent_cli/commands/flow.py +948 -0
- keboola_agent_cli/commands/http_client.py +157 -0
- keboola_agent_cli/commands/init.py +279 -0
- keboola_agent_cli/commands/job.py +661 -0
- keboola_agent_cli/commands/kai.py +301 -0
- keboola_agent_cli/commands/lineage.py +1464 -0
- keboola_agent_cli/commands/org.py +292 -0
- keboola_agent_cli/commands/permissions.py +360 -0
- keboola_agent_cli/commands/project.py +1192 -0
- keboola_agent_cli/commands/repl.py +243 -0
- keboola_agent_cli/commands/schedule.py +340 -0
- keboola_agent_cli/commands/search.py +178 -0
- keboola_agent_cli/commands/semantic_layer.py +939 -0
- keboola_agent_cli/commands/serve.py +272 -0
- keboola_agent_cli/commands/sharing.py +340 -0
- keboola_agent_cli/commands/storage.py +2630 -0
- keboola_agent_cli/commands/stream.py +266 -0
- keboola_agent_cli/commands/sync.py +1277 -0
- keboola_agent_cli/commands/tool.py +206 -0
- keboola_agent_cli/commands/version.py +186 -0
- keboola_agent_cli/commands/workspace.py +635 -0
- keboola_agent_cli/config_store.py +582 -0
- keboola_agent_cli/constants.py +528 -0
- keboola_agent_cli/data_science_client.py +342 -0
- keboola_agent_cli/dev_portal_client.py +323 -0
- keboola_agent_cli/errors.py +248 -0
- keboola_agent_cli/http_base.py +315 -0
- keboola_agent_cli/json_utils.py +126 -0
- keboola_agent_cli/lib.py +536 -0
- keboola_agent_cli/manage_client.py +324 -0
- keboola_agent_cli/metastore_client.py +214 -0
- keboola_agent_cli/models.py +427 -0
- keboola_agent_cli/output.py +1084 -0
- keboola_agent_cli/permissions.py +469 -0
- keboola_agent_cli/py.typed +3 -0
- keboola_agent_cli/result_models.py +271 -0
- keboola_agent_cli/server/__init__.py +34 -0
- keboola_agent_cli/server/agent_runner.py +1289 -0
- keboola_agent_cli/server/agents_store.py +325 -0
- keboola_agent_cli/server/app.py +764 -0
- keboola_agent_cli/server/auth.py +117 -0
- keboola_agent_cli/server/dependencies.py +149 -0
- keboola_agent_cli/server/pricing.py +303 -0
- keboola_agent_cli/server/routers/__init__.py +1 -0
- keboola_agent_cli/server/routers/agents.py +616 -0
- keboola_agent_cli/server/routers/ai_chat.py +129 -0
- keboola_agent_cli/server/routers/branches.py +133 -0
- keboola_agent_cli/server/routers/components.py +48 -0
- keboola_agent_cli/server/routers/configs.py +507 -0
- keboola_agent_cli/server/routers/data_apps.py +384 -0
- keboola_agent_cli/server/routers/dev_portal.py +67 -0
- keboola_agent_cli/server/routers/encrypt.py +35 -0
- keboola_agent_cli/server/routers/feature.py +179 -0
- keboola_agent_cli/server/routers/flows.py +204 -0
- keboola_agent_cli/server/routers/health.py +53 -0
- keboola_agent_cli/server/routers/jobs.py +175 -0
- keboola_agent_cli/server/routers/kai.py +80 -0
- keboola_agent_cli/server/routers/lineage.py +226 -0
- keboola_agent_cli/server/routers/mcp.py +70 -0
- keboola_agent_cli/server/routers/members.py +170 -0
- keboola_agent_cli/server/routers/org.py +96 -0
- keboola_agent_cli/server/routers/projects.py +106 -0
- keboola_agent_cli/server/routers/schedules.py +54 -0
- keboola_agent_cli/server/routers/search.py +30 -0
- keboola_agent_cli/server/routers/semantic_layer.py +650 -0
- keboola_agent_cli/server/routers/sharing.py +86 -0
- keboola_agent_cli/server/routers/storage.py +574 -0
- keboola_agent_cli/server/routers/stream.py +100 -0
- keboola_agent_cli/server/routers/workspaces.py +302 -0
- keboola_agent_cli/server/run_broadcaster.py +329 -0
- keboola_agent_cli/server/sse.py +25 -0
- keboola_agent_cli/services/__init__.py +0 -0
- keboola_agent_cli/services/_encryption.py +217 -0
- keboola_agent_cli/services/_semantic_layer_cascade.py +147 -0
- keboola_agent_cli/services/_semantic_layer_crud.py +382 -0
- keboola_agent_cli/services/_semantic_layer_internals.py +1078 -0
- keboola_agent_cli/services/_semantic_layer_lookup.py +181 -0
- keboola_agent_cli/services/_semantic_layer_reference_data.py +217 -0
- keboola_agent_cli/services/_sync_bindings.py +456 -0
- keboola_agent_cli/services/_sync_branch.py +191 -0
- keboola_agent_cli/services/_sync_bulk.py +228 -0
- keboola_agent_cli/services/_sync_clone.py +163 -0
- keboola_agent_cli/services/_sync_models.py +97 -0
- keboola_agent_cli/services/_sync_push_ops.py +369 -0
- keboola_agent_cli/services/_sync_storage.py +376 -0
- keboola_agent_cli/services/_sync_writeback.py +167 -0
- keboola_agent_cli/services/agent_service.py +458 -0
- keboola_agent_cli/services/base.py +175 -0
- keboola_agent_cli/services/branch_service.py +588 -0
- keboola_agent_cli/services/component_service.py +694 -0
- keboola_agent_cli/services/config_service.py +2099 -0
- keboola_agent_cli/services/data_app_git_service.py +224 -0
- keboola_agent_cli/services/data_app_service.py +2082 -0
- keboola_agent_cli/services/deep_lineage_service.py +1322 -0
- keboola_agent_cli/services/dev_portal_service.py +345 -0
- keboola_agent_cli/services/doctor_service.py +445 -0
- keboola_agent_cli/services/encrypt_service.py +87 -0
- keboola_agent_cli/services/feature_service.py +268 -0
- keboola_agent_cli/services/flow_service.py +769 -0
- keboola_agent_cli/services/flow_validation.py +188 -0
- keboola_agent_cli/services/http_forwarder_service.py +236 -0
- keboola_agent_cli/services/job_idempotency_store.py +285 -0
- keboola_agent_cli/services/job_service.py +797 -0
- keboola_agent_cli/services/kai_service.py +367 -0
- keboola_agent_cli/services/lineage_service.py +274 -0
- keboola_agent_cli/services/mcp_service.py +1498 -0
- keboola_agent_cli/services/mcp_transport.py +259 -0
- keboola_agent_cli/services/member_service.py +593 -0
- keboola_agent_cli/services/org_service.py +619 -0
- keboola_agent_cli/services/project_service.py +947 -0
- keboola_agent_cli/services/repo_validate_service.py +767 -0
- keboola_agent_cli/services/schedule_service.py +731 -0
- keboola_agent_cli/services/search_service.py +331 -0
- keboola_agent_cli/services/semantic_layer_service.py +1497 -0
- keboola_agent_cli/services/sharing_service.py +307 -0
- keboola_agent_cli/services/storage_service.py +2524 -0
- keboola_agent_cli/services/stream_service.py +395 -0
- keboola_agent_cli/services/sync_service.py +2244 -0
- keboola_agent_cli/services/variables_service.py +447 -0
- keboola_agent_cli/services/version_service.py +1038 -0
- keboola_agent_cli/services/workspace_service.py +1103 -0
- keboola_agent_cli/stream_client.py +217 -0
- keboola_agent_cli/sync/__init__.py +1 -0
- keboola_agent_cli/sync/branch_mapping.py +174 -0
- keboola_agent_cli/sync/clone.py +211 -0
- keboola_agent_cli/sync/code_extraction.py +655 -0
- keboola_agent_cli/sync/config_format.py +290 -0
- keboola_agent_cli/sync/diff_engine.py +566 -0
- keboola_agent_cli/sync/git_utils.py +93 -0
- keboola_agent_cli/sync/manifest.py +162 -0
- keboola_agent_cli/sync/naming.py +90 -0
- keboola_agent_cli/sync/secrets.py +62 -0
- keboola_agent_cli/sync/sql_split.py +134 -0
- keboola_cli-0.63.4.dist-info/METADATA +308 -0
- keboola_cli-0.63.4.dist-info/RECORD +306 -0
- keboola_cli-0.63.4.dist-info/WHEEL +4 -0
- keboola_cli-0.63.4.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
"""Pydantic models shared across all layers of the application."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Any
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field, field_validator
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def normalize_stack_url(value: str) -> str:
|
|
11
|
+
"""Normalize a user-supplied Keboola stack URL to its scheme+host base.
|
|
12
|
+
|
|
13
|
+
Accepts, in order of forgiveness:
|
|
14
|
+
- a bare host ``connection.keboola.com``
|
|
15
|
+
- a full base URL ``https://connection.keboola.com``
|
|
16
|
+
- a full base URL + slash ``https://connection.keboola.com/``
|
|
17
|
+
- a full project deep-link ``https://connection.keboola.com/admin/projects/10105/dashboard``
|
|
18
|
+
|
|
19
|
+
and reduces every form to ``https://<host>`` (path/query/fragment dropped).
|
|
20
|
+
A missing scheme defaults to ``https://``. Any *explicit* non-https scheme
|
|
21
|
+
(``http://``, ``file://``, ``ftp://``, ...) is rejected -- this is an
|
|
22
|
+
SSRF / protocol-abuse guard, so we never silently upgrade a typed-out
|
|
23
|
+
``http://`` to https.
|
|
24
|
+
|
|
25
|
+
Raises:
|
|
26
|
+
ValueError: empty input, an explicit non-https scheme, or no host.
|
|
27
|
+
"""
|
|
28
|
+
raw = value.strip()
|
|
29
|
+
if not raw:
|
|
30
|
+
raise ValueError("Stack URL must not be empty.")
|
|
31
|
+
# No scheme typed -> assume https so urlparse sees a netloc, not a path.
|
|
32
|
+
if "://" not in raw:
|
|
33
|
+
raw = f"https://{raw}"
|
|
34
|
+
parsed = urlparse(raw)
|
|
35
|
+
if parsed.scheme != "https":
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Stack URL must use https:// scheme, got: {parsed.scheme or '(none)'}://. "
|
|
38
|
+
"Plain HTTP, file://, and other protocols are not allowed."
|
|
39
|
+
)
|
|
40
|
+
if not parsed.netloc:
|
|
41
|
+
raise ValueError(
|
|
42
|
+
f"Stack URL has no host: {value!r}. Expected e.g. "
|
|
43
|
+
"'connection.keboola.com' or 'https://connection.keboola.com'."
|
|
44
|
+
)
|
|
45
|
+
return f"https://{parsed.netloc}"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ProjectConfig(BaseModel):
|
|
49
|
+
"""Configuration for a single Keboola project connection."""
|
|
50
|
+
|
|
51
|
+
stack_url: str = Field(description="Keboola stack URL, e.g. https://connection.keboola.com")
|
|
52
|
+
token: str = Field(description="Storage API token")
|
|
53
|
+
project_name: str = Field(
|
|
54
|
+
default="", description="Human-readable project name (populated on add)"
|
|
55
|
+
)
|
|
56
|
+
project_id: int | None = Field(
|
|
57
|
+
default=None, description="Keboola project ID (populated on add)"
|
|
58
|
+
)
|
|
59
|
+
active_branch_id: int | None = Field(
|
|
60
|
+
default=None,
|
|
61
|
+
description="Active development branch ID (None = main/production branch)",
|
|
62
|
+
)
|
|
63
|
+
org_id: int | None = Field(
|
|
64
|
+
default=None,
|
|
65
|
+
description="Organization ID (populated via `org setup` or when verify_token returns it)",
|
|
66
|
+
)
|
|
67
|
+
org_name: str | None = Field(
|
|
68
|
+
default=None,
|
|
69
|
+
description="Organization name (populated via `org setup` or when verify_token returns it)",
|
|
70
|
+
)
|
|
71
|
+
ephemeral: bool = Field(
|
|
72
|
+
default=False,
|
|
73
|
+
exclude=True,
|
|
74
|
+
description=(
|
|
75
|
+
"True for an in-memory project synthesized from KBC_TOKEN + "
|
|
76
|
+
"KBC_STORAGE_API_URL (headless mode, issue #359). Excluded from "
|
|
77
|
+
"serialization and stripped by ConfigStore.save() so the env "
|
|
78
|
+
"token is never written to disk."
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
@field_validator("stack_url")
|
|
83
|
+
@classmethod
|
|
84
|
+
def validate_stack_url_scheme(cls, v: str) -> str:
|
|
85
|
+
"""Normalize the stack URL to ``https://<host>`` (see ``normalize_stack_url``).
|
|
86
|
+
|
|
87
|
+
Accepts a bare host, a full base URL, or a full project deep-link and
|
|
88
|
+
reduces it to the scheme+host base; rejects explicit non-https schemes
|
|
89
|
+
(SSRF / protocol-abuse guard).
|
|
90
|
+
"""
|
|
91
|
+
return normalize_stack_url(v)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class DeveloperPortalIdentity(BaseModel):
|
|
95
|
+
"""One Developer Portal identity (service account or admin email).
|
|
96
|
+
|
|
97
|
+
DP login is email + password (with MFA on personal accounts), producing
|
|
98
|
+
a short-lived bearer that lives only in process memory. The username +
|
|
99
|
+
password are persisted in config.json under the same 0600 protection as
|
|
100
|
+
KB Storage tokens; the bearer is never written to disk.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
username: str = Field(description="Email or service-account id used as the login subject")
|
|
104
|
+
password: str = Field(description="DP password — same protection as KB tokens")
|
|
105
|
+
role_hint: str = Field(
|
|
106
|
+
default="vendor",
|
|
107
|
+
description=(
|
|
108
|
+
"Identity role: 'vendor' (default) or 'admin'. Load-bearing -- "
|
|
109
|
+
"write commands route to different apps-api endpoints based on "
|
|
110
|
+
"role: 'admin' uses PATCH /admin/apps/{app} (permissive schema, "
|
|
111
|
+
"can set complexity/categories/forwardToken/processTimeout/etc.); "
|
|
112
|
+
"'vendor' uses PATCH /vendors/{vendor}/apps/{app} (those fields "
|
|
113
|
+
"are forbidden()). kbagent does not verify the server-side role "
|
|
114
|
+
"of the credential -- if you set 'admin' but the account isn't "
|
|
115
|
+
"actually a portal admin, the write fails at the apps-api with "
|
|
116
|
+
"an unambiguous 403."
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
vendor: str | None = Field(
|
|
120
|
+
default=None,
|
|
121
|
+
description=(
|
|
122
|
+
"Optional default vendor for this identity (e.g. 'keboola'). "
|
|
123
|
+
"Used as a default for commands that take --vendor; never "
|
|
124
|
+
"overrides an explicit flag."
|
|
125
|
+
),
|
|
126
|
+
)
|
|
127
|
+
portal_url: str = Field(
|
|
128
|
+
default="https://apps-api.keboola.com",
|
|
129
|
+
description="DP base URL. Override for staging/test portals.",
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@field_validator("portal_url")
|
|
133
|
+
@classmethod
|
|
134
|
+
def validate_portal_url(cls, v: str) -> str:
|
|
135
|
+
"""Enforce HTTPS scheme on portal URL to prevent SSRF and protocol abuse."""
|
|
136
|
+
if not v.startswith("https://"):
|
|
137
|
+
raise ValueError(f"Portal URL must use https:// scheme, got: {v!r}")
|
|
138
|
+
return v
|
|
139
|
+
|
|
140
|
+
@field_validator("role_hint", mode="before")
|
|
141
|
+
@classmethod
|
|
142
|
+
def validate_role_hint(cls, v: object) -> str:
|
|
143
|
+
"""Normalise `role_hint` to the validated enum {vendor, admin}.
|
|
144
|
+
|
|
145
|
+
Before v0.51.1 the field was free-text and documented as "not
|
|
146
|
+
validated against the portal", so existing on-disk configs may
|
|
147
|
+
carry arbitrary strings (e.g. 'keboola-admin', empty string,
|
|
148
|
+
non-string types from hand-edits). A strict raise would crash
|
|
149
|
+
`ConfigStore.load()` -> the entire CLI on startup for every
|
|
150
|
+
pre-0.51.1 user with a non-standard value; that's a worse UX
|
|
151
|
+
than a silent downgrade.
|
|
152
|
+
|
|
153
|
+
Behaviour:
|
|
154
|
+
- "vendor" / "admin" (case-insensitive, whitespace-stripped)
|
|
155
|
+
pass through normalised.
|
|
156
|
+
- Anything else is downgraded to "vendor" with a one-shot stderr
|
|
157
|
+
warning. The user still sees what happened; the CLI keeps
|
|
158
|
+
working. To force admin routing they can rerun
|
|
159
|
+
`dev-portal identity edit --alias A --role-hint admin`.
|
|
160
|
+
"""
|
|
161
|
+
if not isinstance(v, str):
|
|
162
|
+
v = "" if v is None else str(v)
|
|
163
|
+
normalized = v.strip().lower()
|
|
164
|
+
if normalized in ("vendor", "admin"):
|
|
165
|
+
return normalized
|
|
166
|
+
sys.stderr.write(
|
|
167
|
+
f"Warning: role_hint={v!r} is not 'vendor' or 'admin' -- "
|
|
168
|
+
"downgrading to 'vendor'. Use `kbagent dev-portal identity "
|
|
169
|
+
"edit --alias <A> --role-hint admin` to switch.\n"
|
|
170
|
+
)
|
|
171
|
+
return "vendor"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class PermissionPolicy(BaseModel):
|
|
175
|
+
"""Firewall-style permission policy for CLI and MCP operations.
|
|
176
|
+
|
|
177
|
+
Controls which operations are allowed/blocked:
|
|
178
|
+
- mode='allow' (default-allow): everything allowed unless in deny list
|
|
179
|
+
- mode='deny' (default-deny): everything denied unless in allow list
|
|
180
|
+
|
|
181
|
+
Patterns support exact names, globs, and categories:
|
|
182
|
+
- Exact: 'branch.delete', 'tool:create_config'
|
|
183
|
+
- Glob: 'sync.*', 'tool:create_*'
|
|
184
|
+
- Category: 'cli:write', 'cli:read', 'tool:write', 'tool:read'
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
mode: str = Field(
|
|
188
|
+
default="allow",
|
|
189
|
+
description="Base mode: 'allow' (default-allow) or 'deny' (default-deny)",
|
|
190
|
+
)
|
|
191
|
+
allow: list[str] = Field(
|
|
192
|
+
default_factory=list,
|
|
193
|
+
description="Allowed operation patterns (used when mode='deny')",
|
|
194
|
+
)
|
|
195
|
+
deny: list[str] = Field(
|
|
196
|
+
default_factory=list,
|
|
197
|
+
description="Denied operation patterns (used when mode='allow')",
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
@field_validator("mode")
|
|
201
|
+
@classmethod
|
|
202
|
+
def validate_mode(cls, v: str) -> str:
|
|
203
|
+
"""Enforce valid mode values."""
|
|
204
|
+
if v not in ("allow", "deny"):
|
|
205
|
+
raise ValueError(f"Permission mode must be 'allow' or 'deny', got: {v!r}")
|
|
206
|
+
return v
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class AppConfig(BaseModel):
|
|
210
|
+
"""Top-level application configuration persisted to config.json."""
|
|
211
|
+
|
|
212
|
+
version: int = Field(default=1, description="Config schema version for future migrations")
|
|
213
|
+
default_project: str = Field(default="", description="Alias of the default project")
|
|
214
|
+
max_parallel_workers: int = Field(
|
|
215
|
+
default=10,
|
|
216
|
+
ge=1,
|
|
217
|
+
le=100,
|
|
218
|
+
description="Max concurrent threads for multi-project operations (env: KBAGENT_MAX_PARALLEL_WORKERS)",
|
|
219
|
+
)
|
|
220
|
+
permissions: PermissionPolicy | None = Field(
|
|
221
|
+
default=None,
|
|
222
|
+
description="Firewall-style permission policy (None = no restrictions)",
|
|
223
|
+
)
|
|
224
|
+
projects: dict[str, ProjectConfig] = Field(
|
|
225
|
+
default_factory=dict,
|
|
226
|
+
description="Map of alias -> ProjectConfig",
|
|
227
|
+
)
|
|
228
|
+
dev_portal_identities: dict[str, DeveloperPortalIdentity] = Field(
|
|
229
|
+
default_factory=dict,
|
|
230
|
+
description="Map of alias -> DeveloperPortalIdentity",
|
|
231
|
+
)
|
|
232
|
+
default_dev_portal_identity: str = Field(
|
|
233
|
+
default="",
|
|
234
|
+
description="Alias of the default identity for `kbagent dev-portal` commands",
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class TokenVerifyResponse(BaseModel):
|
|
239
|
+
"""Response from the Keboola token verification endpoint."""
|
|
240
|
+
|
|
241
|
+
token_id: str = Field(description="Token identifier")
|
|
242
|
+
token_description: str = Field(description="Human-readable token description")
|
|
243
|
+
project_id: int | None = Field(default=None, description="Keboola project numeric ID")
|
|
244
|
+
project_name: str = Field(description="Keboola project name")
|
|
245
|
+
owner_name: str = Field(description="Project owner name")
|
|
246
|
+
default_backend: str = Field(
|
|
247
|
+
default="snowflake",
|
|
248
|
+
description="Project default backend (snowflake, bigquery, etc.)",
|
|
249
|
+
)
|
|
250
|
+
features: list[str] = Field(
|
|
251
|
+
default_factory=list,
|
|
252
|
+
description="Project feature flags (e.g. agent-chat, storage-types)",
|
|
253
|
+
)
|
|
254
|
+
org_id: int | None = Field(
|
|
255
|
+
default=None,
|
|
256
|
+
description="Organization ID parsed from owner.organization (when present)",
|
|
257
|
+
)
|
|
258
|
+
org_name: str | None = Field(
|
|
259
|
+
default=None,
|
|
260
|
+
description="Organization name parsed from owner.organization (when present)",
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class ComponentDetail(BaseModel):
|
|
265
|
+
"""Component detail from Keboola AI Service /docs/components/{id} endpoint."""
|
|
266
|
+
|
|
267
|
+
component_id: str = Field(alias="componentId")
|
|
268
|
+
component_name: str = Field(alias="componentName")
|
|
269
|
+
component_type: str = Field(alias="componentType")
|
|
270
|
+
component_categories: list[str] = Field(default_factory=list, alias="componentCategories")
|
|
271
|
+
component_flags: list[str] = Field(default_factory=list, alias="componentFlags")
|
|
272
|
+
description: str = Field(default="")
|
|
273
|
+
long_description: str = Field(default="", alias="longDescription")
|
|
274
|
+
documentation: str = Field(default="")
|
|
275
|
+
documentation_url: str = Field(default="", alias="documentationUrl")
|
|
276
|
+
|
|
277
|
+
@field_validator(
|
|
278
|
+
"description", "long_description", "documentation", "documentation_url", mode="before"
|
|
279
|
+
)
|
|
280
|
+
@classmethod
|
|
281
|
+
def _none_to_empty_string(cls, value: Any) -> Any:
|
|
282
|
+
"""AI Service returns explicit null for missing docs (e.g. keboola.flow)."""
|
|
283
|
+
return "" if value is None else value
|
|
284
|
+
|
|
285
|
+
configuration_schema: dict[str, Any] = Field(default_factory=dict, alias="configurationSchema")
|
|
286
|
+
configuration_row_schema: dict[str, Any] = Field(
|
|
287
|
+
default_factory=dict, alias="configurationRowSchema"
|
|
288
|
+
)
|
|
289
|
+
root_configuration_examples: list[dict[str, Any]] = Field(
|
|
290
|
+
default_factory=list, alias="rootConfigurationExamples"
|
|
291
|
+
)
|
|
292
|
+
row_configuration_examples: list[dict[str, Any]] = Field(
|
|
293
|
+
default_factory=list, alias="rowConfigurationExamples"
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
model_config = {"populate_by_name": True}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class ComponentSuggestion(BaseModel):
|
|
300
|
+
"""Single result from AI Service /suggest/component endpoint."""
|
|
301
|
+
|
|
302
|
+
component_id: str = Field(alias="componentId")
|
|
303
|
+
score: float = Field(default=0.0)
|
|
304
|
+
source: str = Field(default="")
|
|
305
|
+
|
|
306
|
+
model_config = {"populate_by_name": True}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class ErrorResponse(BaseModel):
|
|
310
|
+
"""Structured error response for JSON output mode."""
|
|
311
|
+
|
|
312
|
+
code: str = Field(description="Machine-readable error code, e.g. INVALID_TOKEN")
|
|
313
|
+
error_type: str = Field(
|
|
314
|
+
default="unknown",
|
|
315
|
+
description="Broad error category: authentication, network, configuration, not_found, validation, api, unknown",
|
|
316
|
+
)
|
|
317
|
+
message: str = Field(description="Human-readable error description")
|
|
318
|
+
project: str = Field(default="", description="Project alias related to the error, if any")
|
|
319
|
+
retryable: bool = Field(default=False, description="Whether the operation can be retried")
|
|
320
|
+
details: dict | None = Field(
|
|
321
|
+
default=None,
|
|
322
|
+
description=(
|
|
323
|
+
"Optional structured context keyed by the producer (e.g. logTail "
|
|
324
|
+
"for failed Queue jobs). Absent when empty so JSON consumers can "
|
|
325
|
+
"assume 'details in err' implies non-empty payload."
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class SuccessResponse(BaseModel):
|
|
331
|
+
"""Structured success response for JSON output mode."""
|
|
332
|
+
|
|
333
|
+
status: str = Field(default="ok", description="Always 'ok' for success responses")
|
|
334
|
+
data: Any = Field(default=None, description="Response payload")
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class ProjectMember(BaseModel):
|
|
338
|
+
"""Active project member as returned by GET /manage/projects/{id}/users.
|
|
339
|
+
|
|
340
|
+
The Manage API returns audit-relevant fields beyond what kbagent renames
|
|
341
|
+
explicitly: ``created``, ``expires``, ``invitor``, ``approver``, ``features``,
|
|
342
|
+
``canAccessLogs``, ``isSuperAdmin``, ``canApproveMergeRequests``. We allow
|
|
343
|
+
extras through unmodified so admins inspecting `--json` output get the full
|
|
344
|
+
audit trail (who invited whom, when, status flags), not a narrow whitelist.
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
id: int = Field(description="Numeric Keboola user ID")
|
|
348
|
+
email: str = Field(description="Member email address")
|
|
349
|
+
name: str = Field(default="", description="Display name (may be empty for stub accounts)")
|
|
350
|
+
role: str = Field(description="Project role: admin | guest | readOnly | share")
|
|
351
|
+
status: str = Field(default="active", description="Membership status")
|
|
352
|
+
mfa_enabled: bool = Field(default=False, alias="mfaEnabled")
|
|
353
|
+
|
|
354
|
+
model_config = {"populate_by_name": True, "extra": "allow"}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
class Feature(BaseModel):
|
|
358
|
+
"""A Keboola feature flag, from GET /manage/features or a project/user object.
|
|
359
|
+
|
|
360
|
+
The Manage API has no published schema for features and the field set
|
|
361
|
+
varies by stack version. Only ``name`` is treated as stable -- it is the
|
|
362
|
+
identifier passed to the add/remove endpoints. Every field defaults to a
|
|
363
|
+
safe empty value and extras pass through unmodified so ``--json`` output
|
|
364
|
+
keeps whatever the stack returned (``id``, ``projectFeature``,
|
|
365
|
+
``adminFeature``, ``canBeManagedViaApi``, ...).
|
|
366
|
+
|
|
367
|
+
Features embedded in a project/user ``features`` array may be returned as
|
|
368
|
+
bare strings rather than objects; the service layer normalises those to
|
|
369
|
+
``{"name": <string>}`` before validation.
|
|
370
|
+
"""
|
|
371
|
+
|
|
372
|
+
name: str = Field(default="", description="Feature code -- the value used to add/remove it")
|
|
373
|
+
title: str = Field(default="", description="Human-readable name shown in the UI")
|
|
374
|
+
description: str = Field(default="")
|
|
375
|
+
type: str = Field(default="", description="Feature category (project | admin | global | ...)")
|
|
376
|
+
|
|
377
|
+
model_config = {"populate_by_name": True, "extra": "allow"}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class InvitationUser(BaseModel):
|
|
381
|
+
"""Invited user inside an Invitation object."""
|
|
382
|
+
|
|
383
|
+
id: int | None = Field(default=None)
|
|
384
|
+
email: str
|
|
385
|
+
name: str = Field(default="")
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
class ProjectInvitation(BaseModel):
|
|
389
|
+
"""Pending project invitation as returned by GET /manage/projects/{id}/invitations.
|
|
390
|
+
|
|
391
|
+
Extras (``created``, ``expires``, ``creator``) pass through unmodified so
|
|
392
|
+
callers can audit when invitations were created and by whom.
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
id: int = Field(description="Invitation ID -- pass to DELETE to cancel")
|
|
396
|
+
role: str = Field(description="Role offered to the invitee")
|
|
397
|
+
reason: str = Field(default="")
|
|
398
|
+
user: InvitationUser = Field(description="The invited user (email + resolved id)")
|
|
399
|
+
|
|
400
|
+
model_config = {"populate_by_name": True, "extra": "allow"}
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class MemberInviteRow(BaseModel):
|
|
404
|
+
"""Per-row outcome of a bulk-invite operation.
|
|
405
|
+
|
|
406
|
+
`status` = 'ok' (created), 'noop' (already invited or already a member),
|
|
407
|
+
'failed' (any other error). `note` carries the human-readable explanation.
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
email: str
|
|
411
|
+
project: str = Field(description="Alias or numeric ID as it appeared in the source CSV row")
|
|
412
|
+
project_id: int | None = Field(default=None, description="Resolved numeric project ID")
|
|
413
|
+
role: str = Field(default="")
|
|
414
|
+
status: str = Field(description="ok | noop | failed")
|
|
415
|
+
note: str = Field(default="")
|
|
416
|
+
invitation_id: int | None = Field(default=None)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
class BulkInviteResult(BaseModel):
|
|
420
|
+
"""Aggregate result of `kbagent project invite --from-csv`."""
|
|
421
|
+
|
|
422
|
+
total: int
|
|
423
|
+
succeeded: int
|
|
424
|
+
noop: int
|
|
425
|
+
failed: int
|
|
426
|
+
rows: list[MemberInviteRow] = Field(default_factory=list)
|
|
427
|
+
dry_run: bool = Field(default=False)
|