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,157 @@
|
|
|
1
|
+
"""`kbagent http` -- thin Typer wrapper for HttpForwarderService.
|
|
2
|
+
|
|
3
|
+
All transport / body parsing / env-var resolution lives in
|
|
4
|
+
``services/http_forwarder_service.py``; this command layer only does
|
|
5
|
+
what CONTRIBUTING.md §3-Layer architecture requires of commands:
|
|
6
|
+
|
|
7
|
+
1. Parse Typer arguments.
|
|
8
|
+
2. Call the service method.
|
|
9
|
+
3. Format and output the result via ``OutputFormatter``.
|
|
10
|
+
4. Catch :class:`ForwarderError` and map ``exit_code`` to ``typer.Exit``.
|
|
11
|
+
|
|
12
|
+
For the "why a service for self-call HTTP" rationale, see the docstring
|
|
13
|
+
of :mod:`keboola_agent_cli.services.http_forwarder_service`.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
from typing import Any
|
|
21
|
+
|
|
22
|
+
import typer
|
|
23
|
+
|
|
24
|
+
from ..constants import HTTP_DEFAULT_TIMEOUT
|
|
25
|
+
from ..services.http_forwarder_service import (
|
|
26
|
+
ForwardedResponse,
|
|
27
|
+
ForwarderError,
|
|
28
|
+
HttpForwarderService,
|
|
29
|
+
)
|
|
30
|
+
from ._helpers import get_formatter
|
|
31
|
+
|
|
32
|
+
http_app = typer.Typer(
|
|
33
|
+
help=(
|
|
34
|
+
"Raw HTTP client against the running `kbagent serve` "
|
|
35
|
+
"(uses KBAGENT_SERVE_URL + KBAGENT_SERVE_TOKEN env vars)."
|
|
36
|
+
),
|
|
37
|
+
no_args_is_help=True,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _print_json(_console: Any, data: Any) -> None:
|
|
42
|
+
"""Human-mode renderer: pipe-safe pretty JSON.
|
|
43
|
+
|
|
44
|
+
Uses ``sys.stdout.write`` instead of ``console.print`` because Rich
|
|
45
|
+
can soft-wrap long strings or escape markup, which breaks downstream
|
|
46
|
+
``json.loads`` consumers. Real-world case: an AI agent piped
|
|
47
|
+
``kbagent http get /openapi.json`` into ``python3 -c "json.load(sys.stdin)"``
|
|
48
|
+
and hit ``JSONDecodeError`` because Rich had reflowed lines. The output
|
|
49
|
+
of ``kbagent http`` is virtually always parsed by something downstream
|
|
50
|
+
(an LLM, a script, jq) -- so machine-clean stdout is the contract.
|
|
51
|
+
"""
|
|
52
|
+
sys.stdout.write(json.dumps(data, indent=2) + "\n")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _resolve_service(ctx: typer.Context) -> HttpForwarderService:
|
|
56
|
+
"""Pull the service from ctx.obj, falling back to a fresh instance.
|
|
57
|
+
|
|
58
|
+
The service is registered in cli.py for normal CLI invocations, but
|
|
59
|
+
the ``http`` subcommands also run inside a few unit-test entry
|
|
60
|
+
points that bypass the cli root callback (where ctx.obj is empty).
|
|
61
|
+
Falling back to a default-constructed instance keeps those callers
|
|
62
|
+
working without a separate fixture; production callers always go
|
|
63
|
+
through the registered instance because cli.py wires it up before
|
|
64
|
+
any command executes.
|
|
65
|
+
"""
|
|
66
|
+
obj = ctx.obj or {}
|
|
67
|
+
svc = obj.get("http_forwarder_service")
|
|
68
|
+
return svc if isinstance(svc, HttpForwarderService) else HttpForwarderService()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _do_request(
|
|
72
|
+
ctx: typer.Context,
|
|
73
|
+
method: str,
|
|
74
|
+
path: str,
|
|
75
|
+
body: str | None,
|
|
76
|
+
timeout: float,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Shared dispatch for get/post/patch/delete -- thin wrapper layer."""
|
|
79
|
+
formatter = get_formatter(ctx)
|
|
80
|
+
service = _resolve_service(ctx)
|
|
81
|
+
try:
|
|
82
|
+
result: ForwardedResponse = service.request(
|
|
83
|
+
method,
|
|
84
|
+
path,
|
|
85
|
+
body=body,
|
|
86
|
+
timeout=timeout,
|
|
87
|
+
)
|
|
88
|
+
except ForwarderError as exc:
|
|
89
|
+
formatter.error(message=exc.message, error_code=exc.error_code)
|
|
90
|
+
raise typer.Exit(code=exc.exit_code) from None
|
|
91
|
+
|
|
92
|
+
if isinstance(result.decoded, (dict, list)):
|
|
93
|
+
formatter.output(result.decoded, human_formatter=_print_json)
|
|
94
|
+
else:
|
|
95
|
+
typer.echo(str(result.decoded))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@http_app.command("get")
|
|
99
|
+
def http_get(
|
|
100
|
+
ctx: typer.Context,
|
|
101
|
+
path: str = typer.Argument(
|
|
102
|
+
..., help="Endpoint path, e.g. /projects or /agents/cron/preview?cron=*+*+*+*+*"
|
|
103
|
+
),
|
|
104
|
+
timeout: float = typer.Option(
|
|
105
|
+
HTTP_DEFAULT_TIMEOUT, "--timeout", help="Request timeout (seconds)"
|
|
106
|
+
),
|
|
107
|
+
) -> None:
|
|
108
|
+
"""GET an endpoint on the running kbagent serve."""
|
|
109
|
+
_do_request(ctx, "GET", path, body=None, timeout=timeout)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@http_app.command("post")
|
|
113
|
+
def http_post(
|
|
114
|
+
ctx: typer.Context,
|
|
115
|
+
path: str = typer.Argument(..., help="Endpoint path, e.g. /agents/test"),
|
|
116
|
+
body: str | None = typer.Option(
|
|
117
|
+
None,
|
|
118
|
+
"--body",
|
|
119
|
+
"-d",
|
|
120
|
+
help="JSON body: inline JSON, @file.json, or - for stdin",
|
|
121
|
+
),
|
|
122
|
+
timeout: float = typer.Option(
|
|
123
|
+
HTTP_DEFAULT_TIMEOUT, "--timeout", help="Request timeout (seconds)"
|
|
124
|
+
),
|
|
125
|
+
) -> None:
|
|
126
|
+
"""POST to an endpoint on the running kbagent serve."""
|
|
127
|
+
_do_request(ctx, "POST", path, body=body, timeout=timeout)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@http_app.command("patch")
|
|
131
|
+
def http_patch(
|
|
132
|
+
ctx: typer.Context,
|
|
133
|
+
path: str = typer.Argument(..., help="Endpoint path"),
|
|
134
|
+
body: str | None = typer.Option(
|
|
135
|
+
None,
|
|
136
|
+
"--body",
|
|
137
|
+
"-d",
|
|
138
|
+
help="JSON body: inline JSON, @file.json, or - for stdin",
|
|
139
|
+
),
|
|
140
|
+
timeout: float = typer.Option(
|
|
141
|
+
HTTP_DEFAULT_TIMEOUT, "--timeout", help="Request timeout (seconds)"
|
|
142
|
+
),
|
|
143
|
+
) -> None:
|
|
144
|
+
"""PATCH an endpoint on the running kbagent serve."""
|
|
145
|
+
_do_request(ctx, "PATCH", path, body=body, timeout=timeout)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@http_app.command("delete")
|
|
149
|
+
def http_delete(
|
|
150
|
+
ctx: typer.Context,
|
|
151
|
+
path: str = typer.Argument(..., help="Endpoint path"),
|
|
152
|
+
timeout: float = typer.Option(
|
|
153
|
+
HTTP_DEFAULT_TIMEOUT, "--timeout", help="Request timeout (seconds)"
|
|
154
|
+
),
|
|
155
|
+
) -> None:
|
|
156
|
+
"""DELETE an endpoint on the running kbagent serve."""
|
|
157
|
+
_do_request(ctx, "DELETE", path, body=None, timeout=timeout)
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"""Init command - initialize a local .kbagent/ workspace in the current directory."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import stat
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
from ..config_store import ConfigStore
|
|
11
|
+
from ..constants import ENV_PROJECT_FROM_ENV, LOCAL_CONFIG_DIR_NAME
|
|
12
|
+
from ..errors import ErrorCode
|
|
13
|
+
from ..models import AppConfig, PermissionPolicy
|
|
14
|
+
from ..output import OutputFormatter
|
|
15
|
+
from ._helpers import get_formatter, get_service
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def init_command(
|
|
19
|
+
ctx: typer.Context,
|
|
20
|
+
from_global: bool = typer.Option(
|
|
21
|
+
False,
|
|
22
|
+
"--from-global",
|
|
23
|
+
help="Copy projects from the global config into the new local workspace.",
|
|
24
|
+
),
|
|
25
|
+
project: list[str] | None = typer.Option(
|
|
26
|
+
None,
|
|
27
|
+
"--project",
|
|
28
|
+
help="Copy only the named project(s) from the global config (repeatable). "
|
|
29
|
+
"Implies --from-global. Without it, all global projects are copied.",
|
|
30
|
+
),
|
|
31
|
+
read_only: bool = typer.Option(
|
|
32
|
+
False,
|
|
33
|
+
"--read-only",
|
|
34
|
+
help="Set read-only permission policy (blocks all write CLI commands and MCP tools).",
|
|
35
|
+
),
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Initialize a local .kbagent/ workspace in the current directory."""
|
|
38
|
+
formatter = get_formatter(ctx)
|
|
39
|
+
cwd = Path.cwd()
|
|
40
|
+
local_dir = cwd / LOCAL_CONFIG_DIR_NAME
|
|
41
|
+
config_path = local_dir / "config.json"
|
|
42
|
+
|
|
43
|
+
if config_path.is_file():
|
|
44
|
+
formatter.output(
|
|
45
|
+
{
|
|
46
|
+
"message": f"Already initialized at {local_dir}",
|
|
47
|
+
"path": str(local_dir),
|
|
48
|
+
"created": False,
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
config = AppConfig()
|
|
54
|
+
|
|
55
|
+
# Check if global config has projects to offer
|
|
56
|
+
global_store: ConfigStore = get_service(ctx, "config_store")
|
|
57
|
+
selected_aliases = project or []
|
|
58
|
+
# An explicit --project filter implies --from-global: there is nowhere else
|
|
59
|
+
# to copy the named projects from, so opt into copying automatically.
|
|
60
|
+
copy_from_global = from_global or bool(selected_aliases)
|
|
61
|
+
|
|
62
|
+
if not copy_from_global and global_store.source == "global":
|
|
63
|
+
try:
|
|
64
|
+
global_config = global_store.load()
|
|
65
|
+
project_count = len(global_config.projects)
|
|
66
|
+
if project_count > 0:
|
|
67
|
+
is_tty = hasattr(sys.stdin, "isatty") and sys.stdin.isatty()
|
|
68
|
+
if not formatter.json_mode and is_tty:
|
|
69
|
+
copy_from_global = typer.confirm(
|
|
70
|
+
f"Global config has {project_count} project(s). Copy to local workspace?",
|
|
71
|
+
default=True,
|
|
72
|
+
)
|
|
73
|
+
else:
|
|
74
|
+
formatter.warning(
|
|
75
|
+
f"Global config has {project_count} project(s) that won't be "
|
|
76
|
+
"available in local workspace. Use --from-global to copy them."
|
|
77
|
+
)
|
|
78
|
+
except Exception:
|
|
79
|
+
pass # Global config unreadable, proceed with empty
|
|
80
|
+
|
|
81
|
+
if copy_from_global:
|
|
82
|
+
if global_store.source != "global":
|
|
83
|
+
formatter.error(
|
|
84
|
+
message=(
|
|
85
|
+
"Cannot use --from-global: active config is not the global config. "
|
|
86
|
+
"Run from a directory without an existing .kbagent/ workspace."
|
|
87
|
+
),
|
|
88
|
+
error_code=ErrorCode.CONFIG_ERROR,
|
|
89
|
+
)
|
|
90
|
+
raise typer.Exit(code=5)
|
|
91
|
+
config = global_store.load()
|
|
92
|
+
if selected_aliases:
|
|
93
|
+
config = _filter_global_projects(config, selected_aliases, formatter)
|
|
94
|
+
|
|
95
|
+
if read_only and len(config.projects) == 0:
|
|
96
|
+
# Read-only locks the config (chmod 0400 + cli:write deny), so an empty
|
|
97
|
+
# read-only workspace cannot accept any project via `project add` afterwards.
|
|
98
|
+
# Refuse to create a useless locked workspace and guide the user to the
|
|
99
|
+
# correct order: init -> project add -> permissions set.
|
|
100
|
+
formatter.error(
|
|
101
|
+
message=(
|
|
102
|
+
"Cannot init --read-only with an empty workspace: read-only blocks "
|
|
103
|
+
"'project add', so you would be locked out. Correct workflow: "
|
|
104
|
+
"1) 'kbagent init' (without --read-only), "
|
|
105
|
+
"2) 'kbagent project add ...', "
|
|
106
|
+
"3) 'kbagent permissions set --mode allow --deny cli:write --deny tool:write' to lock. "
|
|
107
|
+
"Alternatively, use --from-global to seed projects from the global config."
|
|
108
|
+
),
|
|
109
|
+
error_code=ErrorCode.CONFIG_ERROR,
|
|
110
|
+
)
|
|
111
|
+
raise typer.Exit(code=5)
|
|
112
|
+
|
|
113
|
+
if read_only:
|
|
114
|
+
config.permissions = PermissionPolicy(
|
|
115
|
+
mode="allow",
|
|
116
|
+
deny=["cli:write", "tool:write"],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
local_store = ConfigStore(config_dir=local_dir, source="local")
|
|
120
|
+
local_store.save(config)
|
|
121
|
+
|
|
122
|
+
if read_only:
|
|
123
|
+
# Make config.json owner-read-only so other users (agent) can't read or write it.
|
|
124
|
+
# kbagent itself runs as the owner and can still read it.
|
|
125
|
+
config_path.chmod(stat.S_IRUSR) # 0400
|
|
126
|
+
# Create .claude/settings.json to prevent Claude Code from touching the config
|
|
127
|
+
_create_claude_settings(cwd, local_dir)
|
|
128
|
+
|
|
129
|
+
_update_gitignore(cwd)
|
|
130
|
+
|
|
131
|
+
project_count = len(config.projects)
|
|
132
|
+
message = f"Initialized local workspace at {local_dir}"
|
|
133
|
+
if copy_from_global and project_count > 0:
|
|
134
|
+
message += f" (copied {project_count} project(s) from global config)"
|
|
135
|
+
if read_only:
|
|
136
|
+
message += " [read-only mode]"
|
|
137
|
+
|
|
138
|
+
formatter.output(
|
|
139
|
+
{
|
|
140
|
+
"message": message,
|
|
141
|
+
"path": str(local_dir),
|
|
142
|
+
"created": True,
|
|
143
|
+
"projects_copied": project_count if copy_from_global else 0,
|
|
144
|
+
"read_only": read_only,
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _filter_global_projects(
|
|
150
|
+
config: AppConfig,
|
|
151
|
+
selected_aliases: list[str],
|
|
152
|
+
formatter: OutputFormatter,
|
|
153
|
+
) -> AppConfig:
|
|
154
|
+
"""Narrow a global config copy down to the named projects.
|
|
155
|
+
|
|
156
|
+
Validates that every requested alias exists, keeps only the selected
|
|
157
|
+
projects (deduplicated, preserving the order given on the CLI), and
|
|
158
|
+
repoints ``default_project`` if the global default fell outside the
|
|
159
|
+
selection. ``dev_portal_identities`` and ``permissions`` are not
|
|
160
|
+
project-scoped, so they are left untouched.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
config: The freshly loaded global config (mutated in place).
|
|
164
|
+
selected_aliases: Aliases passed via repeated ``--project`` flags.
|
|
165
|
+
formatter: Output formatter for emitting the error on an unknown alias.
|
|
166
|
+
|
|
167
|
+
Raises:
|
|
168
|
+
typer.Exit: Exit code 5 if any requested alias is missing.
|
|
169
|
+
"""
|
|
170
|
+
missing = [alias for alias in selected_aliases if alias not in config.projects]
|
|
171
|
+
if missing:
|
|
172
|
+
available = ", ".join(sorted(config.projects)) or "(none)"
|
|
173
|
+
formatter.error(
|
|
174
|
+
message=(
|
|
175
|
+
f"Unknown project alias(es): {', '.join(missing)}. "
|
|
176
|
+
f"Available in global config: {available}"
|
|
177
|
+
),
|
|
178
|
+
error_code=ErrorCode.CONFIG_ERROR,
|
|
179
|
+
)
|
|
180
|
+
raise typer.Exit(code=5)
|
|
181
|
+
|
|
182
|
+
# Reject env-synthesized projects: a `__env__` project lives only in memory
|
|
183
|
+
# and is stripped on save, so copying it would report success and then
|
|
184
|
+
# silently vanish on the next load. Fail clearly instead -- mirrors
|
|
185
|
+
# `_reject_ephemeral_mutation` (issue #359).
|
|
186
|
+
ephemeral = [alias for alias in selected_aliases if config.projects[alias].ephemeral]
|
|
187
|
+
if ephemeral:
|
|
188
|
+
formatter.error(
|
|
189
|
+
message=(
|
|
190
|
+
"Cannot copy env-synthesized project(s) into a local workspace: "
|
|
191
|
+
f"{', '.join(ephemeral)}. They are derived from "
|
|
192
|
+
f"{ENV_PROJECT_FROM_ENV} and live only in memory, so they would be "
|
|
193
|
+
"stripped on save. Use 'project add' to persist a project instead."
|
|
194
|
+
),
|
|
195
|
+
error_code=ErrorCode.CONFIG_ERROR,
|
|
196
|
+
)
|
|
197
|
+
raise typer.Exit(code=5)
|
|
198
|
+
|
|
199
|
+
# Dedupe while preserving CLI order (dict keeps insertion order).
|
|
200
|
+
filtered = {alias: config.projects[alias] for alias in selected_aliases}
|
|
201
|
+
config.projects = filtered
|
|
202
|
+
if config.default_project not in filtered:
|
|
203
|
+
# Match the codebase fallback convention (config_store uses the same
|
|
204
|
+
# 2-arg form); `filtered` is non-empty here, so "" is never returned.
|
|
205
|
+
config.default_project = next(iter(filtered), "")
|
|
206
|
+
return config
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _create_claude_settings(project_dir: Path, kbagent_dir: Path) -> None:
|
|
210
|
+
"""Create .claude/settings.json to prevent Claude Code from modifying the config.
|
|
211
|
+
|
|
212
|
+
This is a defense-in-depth measure: even if Claude Code somehow bypasses
|
|
213
|
+
the permission policy, it cannot edit the config file or run commands
|
|
214
|
+
that would change the policy.
|
|
215
|
+
"""
|
|
216
|
+
claude_dir = project_dir / ".claude"
|
|
217
|
+
claude_dir.mkdir(exist_ok=True)
|
|
218
|
+
settings_path = claude_dir / "settings.json"
|
|
219
|
+
|
|
220
|
+
# Relative path from project root to kbagent config
|
|
221
|
+
config_rel = f"{kbagent_dir.name}/config.json"
|
|
222
|
+
|
|
223
|
+
settings: dict = {}
|
|
224
|
+
if settings_path.is_file():
|
|
225
|
+
try:
|
|
226
|
+
settings = json.loads(settings_path.read_text(encoding="utf-8"))
|
|
227
|
+
except (json.JSONDecodeError, OSError):
|
|
228
|
+
settings = {}
|
|
229
|
+
|
|
230
|
+
permissions = settings.setdefault("permissions", {})
|
|
231
|
+
deny_list: list[str] = permissions.get("deny", [])
|
|
232
|
+
|
|
233
|
+
# Rules to add:
|
|
234
|
+
# 1. Block direct file operations on config.json
|
|
235
|
+
# 2. Block any Bash command that mentions the config file (chmod, cat >, python, sed, etc.)
|
|
236
|
+
# 3. Block permission-changing CLI commands
|
|
237
|
+
# 4. Block --config-dir bypass (pointing to global config without policy)
|
|
238
|
+
# 5. Block reading the config (agent doesn't need to -- kbagent reads it internally)
|
|
239
|
+
new_rules = [
|
|
240
|
+
f"Read({config_rel})",
|
|
241
|
+
f"Edit({config_rel})",
|
|
242
|
+
f"Write({config_rel})",
|
|
243
|
+
f"Bash(*{config_rel}*)",
|
|
244
|
+
f"Bash(*chmod*{kbagent_dir.name}*)",
|
|
245
|
+
"Bash(kbagent permissions set*)",
|
|
246
|
+
"Bash(kbagent permissions reset*)",
|
|
247
|
+
"Bash(*permissions set*)",
|
|
248
|
+
"Bash(*permissions reset*)",
|
|
249
|
+
"Bash(*--config-dir*)",
|
|
250
|
+
"Bash(*KBAGENT_CONFIG_DIR*)",
|
|
251
|
+
]
|
|
252
|
+
for rule in new_rules:
|
|
253
|
+
if rule not in deny_list:
|
|
254
|
+
deny_list.append(rule)
|
|
255
|
+
|
|
256
|
+
permissions["deny"] = deny_list
|
|
257
|
+
settings["permissions"] = permissions
|
|
258
|
+
|
|
259
|
+
settings_path.write_text(
|
|
260
|
+
json.dumps(settings, indent=2) + "\n",
|
|
261
|
+
encoding="utf-8",
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _update_gitignore(directory: Path) -> None:
|
|
266
|
+
"""Append .kbagent/ to .gitignore if not already listed."""
|
|
267
|
+
gitignore_path = directory / ".gitignore"
|
|
268
|
+
entry = f"{LOCAL_CONFIG_DIR_NAME}/"
|
|
269
|
+
|
|
270
|
+
if gitignore_path.is_file():
|
|
271
|
+
content = gitignore_path.read_text(encoding="utf-8")
|
|
272
|
+
if entry in content.splitlines():
|
|
273
|
+
return
|
|
274
|
+
if not content.endswith("\n"):
|
|
275
|
+
content += "\n"
|
|
276
|
+
content += entry + "\n"
|
|
277
|
+
gitignore_path.write_text(content, encoding="utf-8")
|
|
278
|
+
else:
|
|
279
|
+
gitignore_path.write_text(entry + "\n", encoding="utf-8")
|