procesio-cli 0.1.1__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.
- procesio_cli/__init__.py +18 -0
- procesio_cli/_cli.py +71 -0
- procesio_cli/agents/__init__.py +0 -0
- procesio_cli/agents/_lib/__init__.py +0 -0
- procesio_cli/agents/_lib/actiondef.py +24 -0
- procesio_cli/agents/_lib/errors.py +40 -0
- procesio_cli/agents/_lib/reversibility.py +236 -0
- procesio_cli/agents/_lib/toolrunner.py +141 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PLAYBOOK.md +62 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PROCESIO-INTEROP.md +76 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-TROUBLESHOOTING.md +60 -0
- procesio_cli/agents/connector-builder/README.md +51 -0
- procesio_cli/agents/connector-builder/agent.yaml +61 -0
- procesio_cli/agents/connector-builder/context.py +19 -0
- procesio_cli/agents/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/agents/connector-builder/handlers/checklist.py +71 -0
- procesio_cli/agents/connector-builder/handlers/guidance.py +37 -0
- procesio_cli/agents/connector-builder/handlers/nextstep.py +221 -0
- procesio_cli/agents/connector-builder/handlers/status.py +35 -0
- procesio_cli/agents/connector-builder/knowledge.py +47 -0
- procesio_cli/agents/connector-builder/main.py +93 -0
- procesio_cli/agents/connector-builder/tests/conftest.py +95 -0
- procesio_cli/agents/connector-builder/tests/test_cba_agent.py +148 -0
- procesio_cli/agents/orchestrator/__init__.py +0 -0
- procesio_cli/agents/orchestrator/bootstraplib.py +166 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/00-INDEX.md +60 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/01-PROCESSES.md +230 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/02-FORMS.md +287 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/03-INTEGRATIONS.md +384 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/04-DATABASE.md +293 -0
- procesio_cli/agents/procesio/PROCESIO-API-RELIABILITY-DOCTRINE.md +113 -0
- procesio_cli/agents/procesio/PROCESIO-BEST-PRACTICES.md +316 -0
- procesio_cli/agents/procesio/PROCESIO-BUILD-AND-TEST-PLAYBOOK.md +217 -0
- procesio_cli/agents/procesio/PROCESIO-DATASTORE.md +72 -0
- procesio_cli/agents/procesio/PROCESIO-ENVIRONMENTS.md +62 -0
- procesio_cli/agents/procesio/PROCESIO-SCHEDULING.md +47 -0
- procesio_cli/agents/procesio/PROCESIO-VISUAL-ORGANIZATION.md +175 -0
- procesio_cli/agents/procesio/README.md +97 -0
- procesio_cli/agents/procesio/__init__.py +0 -0
- procesio_cli/agents/procesio/agent.yaml +73 -0
- procesio_cli/agents/procesio/audit.py +226 -0
- procesio_cli/agents/procesio/checklist.py +135 -0
- procesio_cli/agents/procesio/context.py +19 -0
- procesio_cli/agents/procesio/handlers/__init__.py +0 -0
- procesio_cli/agents/procesio/handlers/audit.py +39 -0
- procesio_cli/agents/procesio/handlers/checklist.py +34 -0
- procesio_cli/agents/procesio/handlers/guidance.py +36 -0
- procesio_cli/agents/procesio/handlers/status.py +33 -0
- procesio_cli/agents/procesio/handlers/verify.py +39 -0
- procesio_cli/agents/procesio/knowledge.py +115 -0
- procesio_cli/agents/procesio/main.py +89 -0
- procesio_cli/agents/procesio/tests/__init__.py +0 -0
- procesio_cli/agents/procesio/tests/conftest.py +62 -0
- procesio_cli/agents/procesio/tests/test_audit.py +91 -0
- procesio_cli/agents/procesio/tests/test_checklist.py +28 -0
- procesio_cli/agents/procesio/tests/test_guidance.py +78 -0
- procesio_cli/agents/procesio/tests/test_manifest_sync.py +48 -0
- procesio_cli/agents/procesio/tests/test_verify.py +134 -0
- procesio_cli/agents/procesio/tests/test_workspace_scope.py +97 -0
- procesio_cli/agents/procesio/verifylib.py +222 -0
- procesio_cli/dashboard/README.md +117 -0
- procesio_cli/dashboard/__init__.py +18 -0
- procesio_cli/dashboard/serve.py +98 -0
- procesio_cli/dashboard/server/__init__.py +1 -0
- procesio_cli/dashboard/server/config_schemas.py +92 -0
- procesio_cli/dashboard/server/google.py +103 -0
- procesio_cli/dashboard/server/handler.py +160 -0
- procesio_cli/dashboard/server/inventory.py +213 -0
- procesio_cli/dashboard/server/jobs.py +118 -0
- procesio_cli/dashboard/server/llmtest.py +181 -0
- procesio_cli/dashboard/server/procesio_env.py +94 -0
- procesio_cli/dashboard/server/routes.py +74 -0
- procesio_cli/dashboard/server/runner.py +150 -0
- procesio_cli/dashboard/server/security.py +29 -0
- procesio_cli/dashboard/server/setup.py +211 -0
- procesio_cli/dashboard/server/validate.py +152 -0
- procesio_cli/dashboard/tests/conftest.py +16 -0
- procesio_cli/dashboard/tests/test_dashboard.py +225 -0
- procesio_cli/dashboard/tests/test_procesio_env.py +159 -0
- procesio_cli/dashboard/web/actions.js +274 -0
- procesio_cli/dashboard/web/api.js +79 -0
- procesio_cli/dashboard/web/app.js +385 -0
- procesio_cli/dashboard/web/copilot.js +72 -0
- procesio_cli/dashboard/web/google.js +121 -0
- procesio_cli/dashboard/web/index.html +67 -0
- procesio_cli/dashboard/web/procesio_env.js +187 -0
- procesio_cli/dashboard/web/styles.css +207 -0
- procesio_cli/registry.py +370 -0
- procesio_cli/scripts/build-router.py +249 -0
- procesio_cli/scripts/build-tool-skill.py +202 -0
- procesio_cli/scripts/check-requirements.py +131 -0
- procesio_cli/scripts/check-skill-governance.py +174 -0
- procesio_cli/scripts/evaluate-skill-routing.py +217 -0
- procesio_cli/scripts/evaluate-skills.py +316 -0
- procesio_cli/scripts/get-skill.py +122 -0
- procesio_cli/scripts/list-skills.py +68 -0
- procesio_cli/scripts/list-tools.py +73 -0
- procesio_cli/scripts/run-agent.py +59 -0
- procesio_cli/scripts/run-tool.py +123 -0
- procesio_cli/scripts/secret_scan.py +584 -0
- procesio_cli/scripts/set-credential.py +126 -0
- procesio_cli/scripts/validate-skills.py +530 -0
- procesio_cli/skills/PORTFOLIO.md +134 -0
- procesio_cli/skills/__init__.py +6 -0
- procesio_cli/skills/agent-skill-engineer/SKILL.md +226 -0
- procesio_cli/skills/agent-skill-engineer/evals/evals.json +422 -0
- procesio_cli/skills/agent-skill-engineer/references/authoring-standard.md +178 -0
- procesio_cli/skills/agent-skill-engineer/references/decision-framework.md +107 -0
- procesio_cli/skills/agent-skill-engineer/references/domain-evidence-protocol.md +248 -0
- procesio_cli/skills/agent-skill-engineer/references/evaluation-standard.md +191 -0
- procesio_cli/skills/agent-skill-engineer/references/expert-lenses.md +167 -0
- procesio_cli/skills/agent-skill-engineer/references/field-gate-standard.md +231 -0
- procesio_cli/skills/agent-skill-engineer/references/optimization-protocol.md +233 -0
- procesio_cli/skills/agent-skill-engineer/references/optimizer-contract.md +268 -0
- procesio_cli/skills/agent-skill-engineer/references/portability-standard.md +99 -0
- procesio_cli/skills/agent-skill-engineer/references/research-basis.md +128 -0
- procesio_cli/skills/agent-skill-engineer/references/review-standard.md +143 -0
- procesio_cli/skills/agent-skill-engineer/scripts/audit_skill.py +959 -0
- procesio_cli/skills/agent-skill-engineer/scripts/optimize_skill.py +891 -0
- procesio_cli/skills/agent-skill-engineer/scripts/scaffold_skill.py +397 -0
- procesio_cli/skills/evals/baseline-catalog.json +14 -0
- procesio_cli/skills/evals/baseline-routing-v2.json +38 -0
- procesio_cli/skills/evals/baseline.json +37 -0
- procesio_cli/skills/evals/behavioral.json +367 -0
- procesio_cli/skills/evals/field-boundary-development-v1.json +126 -0
- procesio_cli/skills/evals/field-closeout-correction-development-v1.json +23 -0
- procesio_cli/skills/evals/field-closeout-development-v1.json +89 -0
- procesio_cli/skills/evals/portfolio-pressure-training-v1.json +83 -0
- procesio_cli/skills/evals/routing.json +363 -0
- procesio_cli/skills/evals/validation-baseline.json +4 -0
- procesio_cli/skills/procesio-cli/SKILL.md +134 -0
- procesio_cli/skills/procesio-cli/evals/evals.json +111 -0
- procesio_cli/skills/procesio-cli/evals/workflows.json +16 -0
- procesio_cli/skills/procesio-cli/references/connector-lifecycle.md +47 -0
- procesio_cli/skills/procesio-cli/references/credentials-admin.md +113 -0
- procesio_cli/skills/procesio-cli/references/data-verification.md +71 -0
- procesio_cli/skills/procesio-cli/references/documents-files.md +44 -0
- procesio_cli/skills/procesio-cli/references/form-e2e.md +57 -0
- procesio_cli/skills/procesio-cli/references/operation-contract.md +138 -0
- procesio_cli/skills/procesio-cli/references/process-debugging.md +65 -0
- procesio_cli/skills/procesio-cli/references/process-lifecycle.md +88 -0
- procesio_cli/skills/procesio-cli/references/schedules-webhooks.md +58 -0
- procesio_cli/skills/procesio-cli/references/transport-environments.md +53 -0
- procesio_cli/skills/procesio-cli-maintainer/SKILL.md +84 -0
- procesio_cli/skills/procesio-cli-maintainer/evals/evals.json +116 -0
- procesio_cli/skills/procesio-cli-maintainer/references/change-contract.md +34 -0
- procesio_cli/skills/procesio-cli-maintainer/references/mcp-compatibility.md +13 -0
- procesio_cli/skills/procesio-cli-maintainer/references/skill-authoring.md +51 -0
- procesio_cli/skills/procesio-platform-advisor/SKILL.md +82 -0
- procesio_cli/skills/procesio-platform-advisor/evals/evals.json +116 -0
- procesio_cli/skills/procesio-platform-advisor/references/capability-map.md +22 -0
- procesio_cli/skills/procesio-platform-advisor/references/fit-framework.md +35 -0
- procesio_cli/skills/procesio-platform-advisor/references/freshness-policy.md +25 -0
- procesio_cli/skills/procesio-platform-advisor/references/sizing-method.md +70 -0
- procesio_cli/skills/procesio-platform-advisor/scripts/estimate_capacity.py +99 -0
- procesio_cli/skills/procesio-setup/SKILL.md +180 -0
- procesio_cli/skills/sql-server-optimizer/SKILL.md +86 -0
- procesio_cli/skills/sql-server-optimizer/evals/evals.json +116 -0
- procesio_cli/skills/sql-server-optimizer/references/db-context.md +44 -0
- procesio_cli/skills/sql-server-optimizer/references/generic-mode.md +32 -0
- procesio_cli/skills/sql-server-optimizer/references/procesio-mode.md +40 -0
- procesio_cli/skills/sql-server-optimizer/references/sql-rules.md +43 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-indexes.sql +178 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-procs-and-functions.sql +118 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-tables.sql +367 -0
- procesio_cli/skills/tests/__init__.py +0 -0
- procesio_cli/skills/tests/test_agent_skill_engineer.py +240 -0
- procesio_cli/skills/tests/test_auth_failure_stop.py +25 -0
- procesio_cli/skills/tests/test_capacity_estimator.py +85 -0
- procesio_cli/skills/tests/test_field_boundary_learning.py +100 -0
- procesio_cli/skills/tests/test_field_closeout_learning.py +123 -0
- procesio_cli/skills/tests/test_field_gate_standard.py +76 -0
- procesio_cli/skills/tests/test_operational_playbooks.py +51 -0
- procesio_cli/skills/tests/test_portfolio_pressure_training.py +35 -0
- procesio_cli/skills/tests/test_process_lifecycle_single_run.py +25 -0
- procesio_cli/skills/tests/test_skill_evaluator.py +67 -0
- procesio_cli/skills/tests/test_skill_optimizer.py +473 -0
- procesio_cli/skills/tests/test_skill_portfolio_review.py +70 -0
- procesio_cli/skills/tests/test_skill_release_binding.py +204 -0
- procesio_cli/skills/tests/test_skill_routing.py +74 -0
- procesio_cli/skills/tests/test_skill_scaffold_v2.py +116 -0
- procesio_cli/skills/tests/test_validate_skills.py +115 -0
- procesio_cli/tools/__init__.py +0 -0
- procesio_cli/tools/_lib/README.md +119 -0
- procesio_cli/tools/_lib/__init__.py +0 -0
- procesio_cli/tools/_lib/accounting.py +120 -0
- procesio_cli/tools/_lib/contacts.py +544 -0
- procesio_cli/tools/_lib/creds.py +83 -0
- procesio_cli/tools/_lib/creds_backends.py +578 -0
- procesio_cli/tools/_lib/dbprofiles.py +147 -0
- procesio_cli/tools/_lib/dbquery.py +286 -0
- procesio_cli/tools/_lib/dbschema.py +225 -0
- procesio_cli/tools/_lib/io.py +54 -0
- procesio_cli/tools/_lib/manifest.py +297 -0
- procesio_cli/tools/_lib/skill_release.py +127 -0
- procesio_cli/tools/_lib/skill_resources.py +118 -0
- procesio_cli/tools/_lib/userdata.py +228 -0
- procesio_cli/tools/_lib/webserialize/__init__.py +16 -0
- procesio_cli/tools/_lib/webserialize/admin.py +61 -0
- procesio_cli/tools/_lib/webserialize/client.py +264 -0
- procesio_cli/tools/_lib/webserialize/config.py +96 -0
- procesio_cli/tools/_lib/webserialize/errors.py +27 -0
- procesio_cli/tools/_lib/webserialize/framing.py +45 -0
- procesio_cli/tools/_lib/webserialize/registry.py +47 -0
- procesio_cli/tools/_lib/webserialize/runtime.py +61 -0
- procesio_cli/tools/_lib/webserialize/server.py +510 -0
- procesio_cli/tools/_lib/websession.py +194 -0
- procesio_cli/tools/connector-builder/CONNECTOR-BUILDER-API-NOTES.md +91 -0
- procesio_cli/tools/connector-builder/README.md +101 -0
- procesio_cli/tools/connector-builder/SKILL.md +248 -0
- procesio_cli/tools/connector-builder/__init__.py +7 -0
- procesio_cli/tools/connector-builder/actiondef.py +24 -0
- procesio_cli/tools/connector-builder/client.py +251 -0
- procesio_cli/tools/connector-builder/errors.py +44 -0
- procesio_cli/tools/connector-builder/gen_manifest.py +142 -0
- procesio_cli/tools/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/tools/connector-builder/handlers/admin.py +182 -0
- procesio_cli/tools/connector-builder/handlers/auth.py +74 -0
- procesio_cli/tools/connector-builder/handlers/builds.py +396 -0
- procesio_cli/tools/connector-builder/handlers/common.py +104 -0
- procesio_cli/tools/connector-builder/handlers/files.py +111 -0
- procesio_cli/tools/connector-builder/handlers/raw.py +38 -0
- procesio_cli/tools/connector-builder/handlers/telemetry.py +39 -0
- procesio_cli/tools/connector-builder/main.py +94 -0
- procesio_cli/tools/connector-builder/tests/conftest.py +146 -0
- procesio_cli/tools/connector-builder/tests/test_cb_client.py +86 -0
- procesio_cli/tools/connector-builder/tests/test_cb_dispatch.py +105 -0
- procesio_cli/tools/connector-builder/tests/test_cb_manifest_sync.py +76 -0
- procesio_cli/tools/connector-builder/tests/test_cb_wait.py +123 -0
- procesio_cli/tools/connector-builder/tool.yaml +671 -0
- procesio_cli/tools/framework-map/.gitattributes +2 -0
- procesio_cli/tools/framework-map/README.md +98 -0
- procesio_cli/tools/framework-map/SKILL.md +30 -0
- procesio_cli/tools/framework-map/app.js +188 -0
- procesio_cli/tools/framework-map/fm_builder.py +476 -0
- procesio_cli/tools/framework-map/fm_catalog.py +19 -0
- procesio_cli/tools/framework-map/fm_ro_catalog.py +94 -0
- procesio_cli/tools/framework-map/fm_strings.py +101 -0
- procesio_cli/tools/framework-map/main.py +95 -0
- procesio_cli/tools/framework-map/styles.css +214 -0
- procesio_cli/tools/framework-map/tests/conftest.py +33 -0
- procesio_cli/tools/framework-map/tests/test_fm_build.py +126 -0
- procesio_cli/tools/framework-map/tests/test_fm_manifest_sync.py +63 -0
- procesio_cli/tools/framework-map/tests/test_fm_store_tree.py +75 -0
- procesio_cli/tools/framework-map/tool.yaml +61 -0
- procesio_cli/tools/mysql/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/mysql/README.md +196 -0
- procesio_cli/tools/mysql/SKILL.md +37 -0
- procesio_cli/tools/mysql/__init__.py +0 -0
- procesio_cli/tools/mysql/connection.py +191 -0
- procesio_cli/tools/mysql/main.py +487 -0
- procesio_cli/tools/mysql/profiles.template.json +1 -0
- procesio_cli/tools/mysql/schema.py +434 -0
- procesio_cli/tools/mysql/tests/__init__.py +0 -0
- procesio_cli/tools/mysql/tests/conftest.py +21 -0
- procesio_cli/tools/mysql/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/mysql/tests/test_mysql.py +201 -0
- procesio_cli/tools/mysql/tests/test_mysql_schema.py +337 -0
- procesio_cli/tools/mysql/tool.yaml +112 -0
- procesio_cli/tools/procesio/DTO-SUBTOOLS-NOTE.md +360 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/00-INDEX.md +67 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/01-ANATOMY.md +209 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/02-CODE-INJECTION.md +309 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/03-DOM-CONTRACT.md +370 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/04-INTERACTION-RECIPES.md +600 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/05-STEPPER-AND-MOTION.md +426 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/06-PROCESS-INTEGRATION.md +347 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/07-DEPLOY-WORKFLOW.md +294 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/08-PITFALLS.md +569 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/09-NAVIGATION-AND-HOSTING.md +308 -0
- procesio_cli/tools/procesio/PHASE4-E2E-NOTES.md +594 -0
- procesio_cli/tools/procesio/PROCESIO-API-CORRECTIONS.md +295 -0
- procesio_cli/tools/procesio/PROCESIO-API-NOTES.md +6976 -0
- procesio_cli/tools/procesio/PROCESIO-AUTH-NOTES.md +226 -0
- procesio_cli/tools/procesio/PROCESIO-CARD-BUILD-NOTES.md +183 -0
- procesio_cli/tools/procesio/PROCESIO-CONNECTORS-NOTES.md +141 -0
- procesio_cli/tools/procesio/PROCESIO-CUSTOM-ACTION-NOTES.md +179 -0
- procesio_cli/tools/procesio/PROCESIO-DOCS-FIX-REPORT.md +123 -0
- procesio_cli/tools/procesio/PROCESIO-ENVIRONMENTS-NOTES.md +94 -0
- procesio_cli/tools/procesio/PROCESIO-FE-VALIDATION-NOTES.md +107 -0
- procesio_cli/tools/procesio/PROCESIO-FOREACH-NOTES.md +199 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-API-HANG-NOTE.md +101 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-SUBMISSION-NOTES.md +172 -0
- procesio_cli/tools/procesio/PROCESIO-HTML-TO-DOCX-NOTES.md +110 -0
- procesio_cli/tools/procesio/PROCESIO-INSTANCE-HISTORY-NOTES.md +242 -0
- procesio_cli/tools/procesio/PROCESIO-METERING-NOTES.md +201 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-CODE-NOTES.md +279 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-MODULE-WHITELIST.md +113 -0
- procesio_cli/tools/procesio/PROCESIO-PYTHON-ACTION-NOTES.md +165 -0
- procesio_cli/tools/procesio/PROCESIO-QUERY-STORE-NOTES.md +826 -0
- procesio_cli/tools/procesio/PROCESIO-RECONCILIATION-PATTERNS.md +104 -0
- procesio_cli/tools/procesio/PROCESIO-RESOURCE-MODEL-NOTES.md +1100 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-CRED-OPTIONALITY.md +45 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-NOTES.md +252 -0
- procesio_cli/tools/procesio/PROCESIO-SQL-ACTIONS-NOTES.md +284 -0
- procesio_cli/tools/procesio/PROCESIO-USAGE-GUIDE.md +219 -0
- procesio_cli/tools/procesio/README.md +341 -0
- procesio_cli/tools/procesio/SCHEDULE-INPUT-SECURITY-NOTES.md +63 -0
- procesio_cli/tools/procesio/SKILL.md +694 -0
- procesio_cli/tools/procesio/__init__.py +1 -0
- procesio_cli/tools/procesio/actiondef.py +27 -0
- procesio_cli/tools/procesio/assets/html2docx/html2docx.js +2155 -0
- procesio_cli/tools/procesio/auth.py +354 -0
- procesio_cli/tools/procesio/autogen.py +121 -0
- procesio_cli/tools/procesio/client.py +355 -0
- procesio_cli/tools/procesio/config.py +96 -0
- procesio_cli/tools/procesio/data/endpoints.json +2901 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/01-authentication.md +180 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/02-conventions.md +116 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/ANONYMOUS-SURFACE.md +51 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/README.md +104 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/SYMBOL-INDEX.md +444 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/03-auth-users-workspaces.md +731 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/04-processes.md +913 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/05-actions.md +605 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/06-files.md +237 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/07-forms-documents.md +985 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/08-credentials.md +532 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/09-datastore-datatypes.md +830 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/10-custom-urls.md +319 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/11-subscriptions-resources-analytics.md +455 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/12-webhooks-notifications-misc.md +519 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/13-realtime-signalr.md +153 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/99-internal-and-other-services.md +52 -0
- procesio_cli/tools/procesio/docs_info/FormBuilder mock.ts +5725 -0
- procesio_cli/tools/procesio/docs_info/Procesio Platform Actions.json +30219 -0
- procesio_cli/tools/procesio/docs_info/form-config-enums.ts +92 -0
- procesio_cli/tools/procesio/docs_info/form-theme.ts +1603 -0
- procesio_cli/tools/procesio/docs_info/process-validation-reference-1.md +2739 -0
- procesio_cli/tools/procesio/dto/__init__.py +13 -0
- procesio_cli/tools/procesio/dto/credential/builder.py +179 -0
- procesio_cli/tools/procesio/dto/credential/config.schema.json +19 -0
- procesio_cli/tools/procesio/dto/credential/description.md +193 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.config.json +11 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.dto.json +28 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.template.json +44 -0
- procesio_cli/tools/procesio/dto/credential/template.dto.json +16 -0
- procesio_cli/tools/procesio/dto/data/_refresh.py +147 -0
- procesio_cli/tools/procesio/dto/data/action_catalog.json +30825 -0
- procesio_cli/tools/procesio/dto/data/action_families.json +55 -0
- procesio_cli/tools/procesio/dto/data/platform_types.json +182 -0
- procesio_cli/tools/procesio/dto/datatype/builder.py +223 -0
- procesio_cli/tools/procesio/dto/datatype/config.schema.json +47 -0
- procesio_cli/tools/procesio/dto/datatype/description.md +85 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.config.json +41 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.dto.json +164 -0
- procesio_cli/tools/procesio/dto/datatype/template.dto.json +37 -0
- procesio_cli/tools/procesio/dto/document/builder.py +193 -0
- procesio_cli/tools/procesio/dto/document/config.schema.json +33 -0
- procesio_cli/tools/procesio/dto/document/description.md +124 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.config.json +16 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.dto.json +32 -0
- procesio_cli/tools/procesio/dto/document/template.dto.json +14 -0
- procesio_cli/tools/procesio/dto/form/FORM-STYLING-NOTES.md +142 -0
- procesio_cli/tools/procesio/dto/form/GOLDEN-DRIFT-NOTES.md +72 -0
- procesio_cli/tools/procesio/dto/form/RUN-PROCESS-RESULT-NOTES.md +80 -0
- procesio_cli/tools/procesio/dto/form/addelement.py +277 -0
- procesio_cli/tools/procesio/dto/form/builder.py +1009 -0
- procesio_cli/tools/procesio/dto/form/capture_goldens.py +106 -0
- procesio_cli/tools/procesio/dto/form/code_cipher.py +67 -0
- procesio_cli/tools/procesio/dto/form/config.schema.json +76 -0
- procesio_cli/tools/procesio/dto/form/data_shell.json +1 -0
- procesio_cli/tools/procesio/dto/form/description.md +346 -0
- procesio_cli/tools/procesio/dto/form/elements/approval.json +259 -0
- procesio_cli/tools/procesio/dto/form/elements/assignee.json +137 -0
- procesio_cli/tools/procesio/dto/form/elements/button.json +125 -0
- procesio_cli/tools/procesio/dto/form/elements/chart.json +341 -0
- procesio_cli/tools/procesio/dto/form/elements/chat.json +199 -0
- procesio_cli/tools/procesio/dto/form/elements/checkbox.json +153 -0
- procesio_cli/tools/procesio/dto/form/elements/column.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/columns.json +78 -0
- procesio_cli/tools/procesio/dto/form/elements/datetime-input.json +304 -0
- procesio_cli/tools/procesio/dto/form/elements/divider.json +54 -0
- procesio_cli/tools/procesio/dto/form/elements/dropdown.json +130 -0
- procesio_cli/tools/procesio/dto/form/elements/dynamic-table-row.json +253 -0
- procesio_cli/tools/procesio/dto/form/elements/file-upload.json +196 -0
- procesio_cli/tools/procesio/dto/form/elements/file-viewer.json +169 -0
- procesio_cli/tools/procesio/dto/form/elements/heading.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/icon.json +107 -0
- procesio_cli/tools/procesio/dto/form/elements/image.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/input.json +206 -0
- procesio_cli/tools/procesio/dto/form/elements/list.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/number-input.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/paragraph.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/radiobox.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/section.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/select.json +217 -0
- procesio_cli/tools/procesio/dto/form/elements/side-panel.json +146 -0
- procesio_cli/tools/procesio/dto/form/elements/signature-pad.json +141 -0
- procesio_cli/tools/procesio/dto/form/elements/static-table-row.json +84 -0
- procesio_cli/tools/procesio/dto/form/elements/step.json +105 -0
- procesio_cli/tools/procesio/dto/form/elements/stepper.json +126 -0
- procesio_cli/tools/procesio/dto/form/elements/tab.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/table.json +279 -0
- procesio_cli/tools/procesio/dto/form/elements/tabs.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/textarea.json +213 -0
- procesio_cli/tools/procesio/dto/form/enum_map.json +68 -0
- procesio_cli/tools/procesio/dto/form/fieldpath.py +284 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.config.json +32 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.elements.json +638 -0
- procesio_cli/tools/procesio/dto/form/sync_from_mock.py +386 -0
- procesio_cli/tools/procesio/dto/framework.py +125 -0
- procesio_cli/tools/procesio/dto/process/builder.py +1991 -0
- procesio_cli/tools/procesio/dto/process/config.schema.json +159 -0
- procesio_cli/tools/procesio/dto/process/description.md +218 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.config.json +32 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.dto.json +317 -0
- procesio_cli/tools/procesio/dto/process/naming.py +305 -0
- procesio_cli/tools/procesio/dto/process/normalize.py +74 -0
- procesio_cli/tools/procesio/dto/process/template.dto.json +32 -0
- procesio_cli/tools/procesio/dto/refdata.py +87 -0
- procesio_cli/tools/procesio/dto/registry.py +27 -0
- procesio_cli/tools/procesio/dto/webhook/builder.py +142 -0
- procesio_cli/tools/procesio/dto/webhook/config.schema.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/description.md +92 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.config.json +10 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.dto.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/template.dto.json +14 -0
- procesio_cli/tools/procesio/environments.py +264 -0
- procesio_cli/tools/procesio/errors.py +166 -0
- procesio_cli/tools/procesio/flowmodel/README.md +37 -0
- procesio_cli/tools/procesio/flowmodel/__init__.py +14 -0
- procesio_cli/tools/procesio/flowmodel/digest.py +223 -0
- procesio_cli/tools/procesio/flowmodel/families.py +34 -0
- procesio_cli/tools/procesio/flowmodel/fevalidation.py +1098 -0
- procesio_cli/tools/procesio/flowmodel/formdigest.py +232 -0
- procesio_cli/tools/procesio/flowmodel/inspect.py +78 -0
- procesio_cli/tools/procesio/flowmodel/model.py +82 -0
- procesio_cli/tools/procesio/flowmodel/nodeparam.py +871 -0
- procesio_cli/tools/procesio/flowmodel/reader.py +191 -0
- procesio_cli/tools/procesio/flowmodel/sqlparam.py +410 -0
- procesio_cli/tools/procesio/form_code_keys.py +50 -0
- procesio_cli/tools/procesio/formlint.py +292 -0
- procesio_cli/tools/procesio/gen_manifest.py +118 -0
- procesio_cli/tools/procesio/handlers/__init__.py +1 -0
- procesio_cli/tools/procesio/handlers/auth_actions.py +103 -0
- procesio_cli/tools/procesio/handlers/catalog.py +147 -0
- procesio_cli/tools/procesio/handlers/common.py +90 -0
- procesio_cli/tools/procesio/handlers/customaction_ops.py +146 -0
- procesio_cli/tools/procesio/handlers/datastore_ops.py +482 -0
- procesio_cli/tools/procesio/handlers/datatype_ops.py +275 -0
- procesio_cli/tools/procesio/handlers/dto_actions.py +258 -0
- procesio_cli/tools/procesio/handlers/environment_admin.py +146 -0
- procesio_cli/tools/procesio/handlers/fevalidate.py +236 -0
- procesio_cli/tools/procesio/handlers/files.py +141 -0
- procesio_cli/tools/procesio/handlers/flowgraph.py +229 -0
- procesio_cli/tools/procesio/handlers/flowlint.py +269 -0
- procesio_cli/tools/procesio/handlers/form_chains.py +336 -0
- procesio_cli/tools/procesio/handlers/form_code.py +277 -0
- procesio_cli/tools/procesio/handlers/form_element.py +199 -0
- procesio_cli/tools/procesio/handlers/form_events.py +441 -0
- procesio_cli/tools/procesio/handlers/form_update.py +270 -0
- procesio_cli/tools/procesio/handlers/formprocess.py +211 -0
- procesio_cli/tools/procesio/handlers/generic.py +135 -0
- procesio_cli/tools/procesio/handlers/layout.py +137 -0
- procesio_cli/tools/procesio/handlers/nodeparams.py +1018 -0
- procesio_cli/tools/procesio/handlers/process_layout.py +189 -0
- procesio_cli/tools/procesio/handlers/process_naming.py +213 -0
- procesio_cli/tools/procesio/handlers/processes.py +416 -0
- procesio_cli/tools/procesio/handlers/profile_admin.py +184 -0
- procesio_cli/tools/procesio/handlers/resource_ops.py +447 -0
- procesio_cli/tools/procesio/handlers/schedules.py +320 -0
- procesio_cli/tools/procesio/handlers/sqlactions.py +232 -0
- procesio_cli/tools/procesio/handlers/transport.py +463 -0
- procesio_cli/tools/procesio/handlers/usageguide.py +222 -0
- procesio_cli/tools/procesio/layout/README.md +196 -0
- procesio_cli/tools/procesio/layout/__init__.py +11 -0
- procesio_cli/tools/procesio/layout/adapter.py +736 -0
- procesio_cli/tools/procesio/layout/cycles.py +186 -0
- procesio_cli/tools/procesio/layout/dispatch.py +39 -0
- procesio_cli/tools/procesio/layout/elk/elk_runner.mjs +50 -0
- procesio_cli/tools/procesio/layout/elk/package-lock.json +21 -0
- procesio_cli/tools/procesio/layout/elk/package.json +11 -0
- procesio_cli/tools/procesio/layout/elk_engine.py +568 -0
- procesio_cli/tools/procesio/layout/engine.py +1311 -0
- procesio_cli/tools/procesio/layout/report.py +187 -0
- procesio_cli/tools/procesio/main.py +179 -0
- procesio_cli/tools/procesio/profiles.py +193 -0
- procesio_cli/tools/procesio/reliability.py +193 -0
- procesio_cli/tools/procesio/sqlformat.py +167 -0
- procesio_cli/tools/procesio/swagger.py +51 -0
- procesio_cli/tools/procesio/tests/__init__.py +0 -0
- procesio_cli/tools/procesio/tests/conftest.py +129 -0
- procesio_cli/tools/procesio/tests/test_auth.py +200 -0
- procesio_cli/tools/procesio/tests/test_autogen.py +78 -0
- procesio_cli/tools/procesio/tests/test_builder_attrpath_sqlbind.py +180 -0
- procesio_cli/tools/procesio/tests/test_builder_custom_action_catalog.py +72 -0
- procesio_cli/tools/procesio/tests/test_client.py +114 -0
- procesio_cli/tools/procesio/tests/test_client_reliability.py +139 -0
- procesio_cli/tools/procesio/tests/test_customaction.py +103 -0
- procesio_cli/tools/procesio/tests/test_customaction_test.py +80 -0
- procesio_cli/tools/procesio/tests/test_cycles.py +69 -0
- procesio_cli/tools/procesio/tests/test_datastore.py +378 -0
- procesio_cli/tools/procesio/tests/test_datastore_node.py +94 -0
- procesio_cli/tools/procesio/tests/test_dispatch.py +170 -0
- procesio_cli/tools/procesio/tests/test_document_page_size.py +19 -0
- procesio_cli/tools/procesio/tests/test_dto.py +734 -0
- procesio_cli/tools/procesio/tests/test_edit_dryrun_preview.py +96 -0
- procesio_cli/tools/procesio/tests/test_elk_layout.py +221 -0
- procesio_cli/tools/procesio/tests/test_environments.py +214 -0
- procesio_cli/tools/procesio/tests/test_fevalidate_gate.py +104 -0
- procesio_cli/tools/procesio/tests/test_fevalidation.py +317 -0
- procesio_cli/tools/procesio/tests/test_fieldpath_variables.py +87 -0
- procesio_cli/tools/procesio/tests/test_files.py +72 -0
- procesio_cli/tools/procesio/tests/test_flow_digest.py +202 -0
- procesio_cli/tools/procesio/tests/test_flowlint.py +114 -0
- procesio_cli/tools/procesio/tests/test_flowmodel.py +158 -0
- procesio_cli/tools/procesio/tests/test_form_add_element.py +256 -0
- procesio_cli/tools/procesio/tests/test_form_approval_gaps.py +319 -0
- procesio_cli/tools/procesio/tests/test_form_auto_names.py +60 -0
- procesio_cli/tools/procesio/tests/test_form_chains.py +217 -0
- procesio_cli/tools/procesio/tests/test_form_code_actions.py +188 -0
- procesio_cli/tools/procesio/tests/test_form_code_keys.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_code_style.py +178 -0
- procesio_cli/tools/procesio/tests/test_form_delete_element.py +99 -0
- procesio_cli/tools/procesio/tests/test_form_element_config.py +141 -0
- procesio_cli/tools/procesio/tests/test_form_event_maps.py +135 -0
- procesio_cli/tools/procesio/tests/test_form_event_ops.py +376 -0
- procesio_cli/tools/procesio/tests/test_form_event_replace.py +86 -0
- procesio_cli/tools/procesio/tests/test_form_events.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_parity.py +171 -0
- procesio_cli/tools/procesio/tests/test_form_select_source.py +74 -0
- procesio_cli/tools/procesio/tests/test_form_sync.py +35 -0
- procesio_cli/tools/procesio/tests/test_form_update.py +133 -0
- procesio_cli/tools/procesio/tests/test_formlint.py +155 -0
- procesio_cli/tools/procesio/tests/test_formlint_css_scope.py +38 -0
- procesio_cli/tools/procesio/tests/test_formlint_field_names.py +83 -0
- procesio_cli/tools/procesio/tests/test_guards.py +110 -0
- procesio_cli/tools/procesio/tests/test_hidden_setting_types.py +39 -0
- procesio_cli/tools/procesio/tests/test_html2docx_asset.py +132 -0
- procesio_cli/tools/procesio/tests/test_key_handle_terminology.py +45 -0
- procesio_cli/tools/procesio/tests/test_layout.py +574 -0
- procesio_cli/tools/procesio/tests/test_layout_report.py +88 -0
- procesio_cli/tools/procesio/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/procesio/tests/test_nodedelete.py +151 -0
- procesio_cli/tools/procesio/tests/test_nodeparam.py +826 -0
- procesio_cli/tools/procesio/tests/test_normalize.py +70 -0
- procesio_cli/tools/procesio/tests/test_payload_docs.py +86 -0
- procesio_cli/tools/procesio/tests/test_process_action_naming.py +170 -0
- procesio_cli/tools/procesio/tests/test_process_call_api_seed.py +46 -0
- procesio_cli/tools/procesio/tests/test_process_ext.py +373 -0
- procesio_cli/tools/procesio/tests/test_process_invariants.py +183 -0
- procesio_cli/tools/procesio/tests/test_process_layout.py +117 -0
- procesio_cli/tools/procesio/tests/test_process_naming.py +188 -0
- procesio_cli/tools/procesio/tests/test_process_query_store.py +172 -0
- procesio_cli/tools/procesio/tests/test_processinfo_variable.py +56 -0
- procesio_cli/tools/procesio/tests/test_profiles.py +127 -0
- procesio_cli/tools/procesio/tests/test_put_projects.py +41 -0
- procesio_cli/tools/procesio/tests/test_reliability.py +107 -0
- procesio_cli/tools/procesio/tests/test_removal_gate.py +95 -0
- procesio_cli/tools/procesio/tests/test_resource_ops.py +173 -0
- procesio_cli/tools/procesio/tests/test_save_validity.py +207 -0
- procesio_cli/tools/procesio/tests/test_schedule_cron_shape.py +111 -0
- procesio_cli/tools/procesio/tests/test_schedules.py +309 -0
- procesio_cli/tools/procesio/tests/test_sqlconvert.py +234 -0
- procesio_cli/tools/procesio/tests/test_sqlformat.py +83 -0
- procesio_cli/tools/procesio/tests/test_sqlparam.py +187 -0
- procesio_cli/tools/procesio/tests/test_superseded_actions.py +54 -0
- procesio_cli/tools/procesio/tests/test_surgical_concurrency.py +156 -0
- procesio_cli/tools/procesio/tests/test_tier4.py +123 -0
- procesio_cli/tools/procesio/tests/test_transport.py +147 -0
- procesio_cli/tools/procesio/tests/test_transport_data_stores.py +168 -0
- procesio_cli/tools/procesio/tests/test_transport_mapper_repair.py +150 -0
- procesio_cli/tools/procesio/tests/test_transport_webhook_strip.py +253 -0
- procesio_cli/tools/procesio/tests/test_usage_guide.py +96 -0
- procesio_cli/tools/procesio/tool.yaml +12486 -0
- procesio_cli/tools/sqlserver/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/sqlserver/README.md +192 -0
- procesio_cli/tools/sqlserver/SKILL.md +37 -0
- procesio_cli/tools/sqlserver/SQLSERVER-SCHEMA-NOTES.md +284 -0
- procesio_cli/tools/sqlserver/__init__.py +0 -0
- procesio_cli/tools/sqlserver/connection.py +242 -0
- procesio_cli/tools/sqlserver/main.py +521 -0
- procesio_cli/tools/sqlserver/profiles.template.json +1 -0
- procesio_cli/tools/sqlserver/schema.py +600 -0
- procesio_cli/tools/sqlserver/tests/__init__.py +0 -0
- procesio_cli/tools/sqlserver/tests/conftest.py +21 -0
- procesio_cli/tools/sqlserver/tests/test_connection.py +75 -0
- procesio_cli/tools/sqlserver/tests/test_dbprofiles.py +92 -0
- procesio_cli/tools/sqlserver/tests/test_dbquery.py +220 -0
- procesio_cli/tools/sqlserver/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver.py +326 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver_schema.py +488 -0
- procesio_cli/tools/sqlserver/tool.yaml +123 -0
- procesio_cli/tools/web/README.md +381 -0
- procesio_cli/tools/web/SKILL.md +37 -0
- procesio_cli/tools/web/WEB-AUTOMATION-NOTES.md +277 -0
- procesio_cli/tools/web/__init__.py +21 -0
- procesio_cli/tools/web/actiondef.py +24 -0
- procesio_cli/tools/web/api.py +444 -0
- procesio_cli/tools/web/brokered.py +107 -0
- procesio_cli/tools/web/driver.py +839 -0
- procesio_cli/tools/web/drivercontract.py +44 -0
- procesio_cli/tools/web/errors.py +54 -0
- procesio_cli/tools/web/handlers/__init__.py +1 -0
- procesio_cli/tools/web/handlers/archive.py +367 -0
- procesio_cli/tools/web/handlers/browse.py +182 -0
- procesio_cli/tools/web/handlers/contacts.py +74 -0
- procesio_cli/tools/web/handlers/sessmgmt.py +120 -0
- procesio_cli/tools/web/main.py +128 -0
- procesio_cli/tools/web/sessions.py +253 -0
- procesio_cli/tools/web/steps.py +162 -0
- procesio_cli/tools/web/tests/__init__.py +0 -0
- procesio_cli/tools/web/tests/conftest.py +197 -0
- procesio_cli/tools/web/tests/test_api.py +330 -0
- procesio_cli/tools/web/tests/test_archive.py +190 -0
- procesio_cli/tools/web/tests/test_brokered.py +138 -0
- procesio_cli/tools/web/tests/test_dispatch.py +132 -0
- procesio_cli/tools/web/tests/test_errors.py +60 -0
- procesio_cli/tools/web/tests/test_manifest_sync.py +76 -0
- procesio_cli/tools/web/tests/test_page_contacts.py +68 -0
- procesio_cli/tools/web/tests/test_sessions.py +145 -0
- procesio_cli/tools/web/tests/test_steps.py +210 -0
- procesio_cli/tools/web/tool.yaml +184 -0
- procesio_cli/tools/xlsx/README.md +34 -0
- procesio_cli/tools/xlsx/SKILL.md +28 -0
- procesio_cli/tools/xlsx/__init__.py +0 -0
- procesio_cli/tools/xlsx/main.py +129 -0
- procesio_cli/tools/xlsx/reader.py +91 -0
- procesio_cli/tools/xlsx/tests/__init__.py +0 -0
- procesio_cli/tools/xlsx/tests/conftest.py +39 -0
- procesio_cli/tools/xlsx/tests/test_xlsx.py +103 -0
- procesio_cli/tools/xlsx/tool.yaml +30 -0
- procesio_cli/webplatform/aat_mcp/AAT-MCP-NOTES.md +244 -0
- procesio_cli/webplatform/aat_mcp/README.md +78 -0
- procesio_cli/webplatform/aat_mcp/bridge.py +705 -0
- procesio_cli/webplatform/aat_mcp/chat_server.py +194 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.snapshot.json +668 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.yaml +372 -0
- procesio_cli/webplatform/aat_mcp/gate.py +68 -0
- procesio_cli/webplatform/aat_mcp/http_server.py +139 -0
- procesio_cli/webplatform/aat_mcp/protocol.py +175 -0
- procesio_cli/webplatform/aat_mcp/server.py +306 -0
- procesio_cli/webplatform/aat_mcp/tests/conftest.py +8 -0
- procesio_cli/webplatform/aat_mcp/tests/test_aat_mcp.py +255 -0
- procesio_cli/webplatform/aat_mcp/tests/test_chat_surface.py +247 -0
- procesio_cli/webplatform/aat_mcp/tests/test_discovery.py +489 -0
- procesio_cli/webplatform/aat_mcp/tests/test_multiuser.py +86 -0
- procesio_cli/webplatform/aat_mcp/tests/test_progressive_discovery.py +89 -0
- procesio_cli/webplatform/aat_mcp/tests/test_protocol.py +180 -0
- procesio_cli/webplatform/aat_mcp/tests/test_skill_discovery.py +23 -0
- procesio_cli-0.1.1.dist-info/METADATA +467 -0
- procesio_cli-0.1.1.dist-info/RECORD +647 -0
- procesio_cli-0.1.1.dist-info/WHEEL +4 -0
- procesio_cli-0.1.1.dist-info/entry_points.txt +7 -0
- procesio_cli-0.1.1.dist-info/licenses/LICENSE +201 -0
- procesio_cli-0.1.1.dist-info/licenses/NOTICE +5 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""mysql dispatch + introspection tests against an injected fake cursor.
|
|
2
|
+
|
|
3
|
+
No live DB and no pymysql are needed: we inject a ``conn_factory`` into
|
|
4
|
+
``dispatch``. The connection-kwargs builder + masked DSN are tested directly
|
|
5
|
+
(connection_kwargs imports pymysql only for the DictCursor class, which is
|
|
6
|
+
present in the venv, but never opens a socket).
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import datetime as dt
|
|
11
|
+
import decimal
|
|
12
|
+
|
|
13
|
+
import pytest
|
|
14
|
+
|
|
15
|
+
from tools._lib import dbquery
|
|
16
|
+
from tools.mysql import connection, main
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# --- fake DBAPI (DictCursor-style: rows are dicts) --------------------------
|
|
20
|
+
|
|
21
|
+
class FakeCursor:
|
|
22
|
+
def __init__(self, description, rows):
|
|
23
|
+
self.description = description
|
|
24
|
+
self._rows = rows
|
|
25
|
+
self.executed = []
|
|
26
|
+
self.closed = False
|
|
27
|
+
|
|
28
|
+
def execute(self, sql, params=None):
|
|
29
|
+
self.executed.append((sql, params))
|
|
30
|
+
|
|
31
|
+
def fetchall(self):
|
|
32
|
+
return list(self._rows)
|
|
33
|
+
|
|
34
|
+
def close(self):
|
|
35
|
+
self.closed = True
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class FakeConn:
|
|
39
|
+
def __init__(self, queue):
|
|
40
|
+
self._queue = list(queue)
|
|
41
|
+
self.cursors = []
|
|
42
|
+
self.closed = False
|
|
43
|
+
|
|
44
|
+
def cursor(self):
|
|
45
|
+
cur = self._queue.pop(0)
|
|
46
|
+
self.cursors.append(cur)
|
|
47
|
+
return cur
|
|
48
|
+
|
|
49
|
+
def close(self):
|
|
50
|
+
self.closed = True
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _factory(*cursors):
|
|
54
|
+
conn = FakeConn(cursors)
|
|
55
|
+
return lambda _profile: conn, conn
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.fixture
|
|
59
|
+
def one_profile(tmp_path, monkeypatch):
|
|
60
|
+
from tools._lib import dbprofiles
|
|
61
|
+
pfile = tmp_path / "profiles.json"
|
|
62
|
+
monkeypatch.setattr(main, "PROFILES_PATH", pfile)
|
|
63
|
+
monkeypatch.setattr(dbprofiles.creds, "has", lambda *a: False)
|
|
64
|
+
monkeypatch.setattr(dbprofiles.creds, "get_optional", lambda *a: None)
|
|
65
|
+
main._store().add("default", {"host": "h", "database": "d", "username": "u"})
|
|
66
|
+
return pfile
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_dispatch_query_database_override(one_profile):
|
|
70
|
+
"""--database overrides the profile's database, so ONE profile (one host +
|
|
71
|
+
login + credential) can query any database on that host."""
|
|
72
|
+
captured = {}
|
|
73
|
+
conn = FakeConn([FakeCursor(description=[], rows=[])])
|
|
74
|
+
|
|
75
|
+
def factory(profile):
|
|
76
|
+
captured["db"] = profile.get("database")
|
|
77
|
+
return conn
|
|
78
|
+
|
|
79
|
+
main.dispatch(
|
|
80
|
+
"query",
|
|
81
|
+
["--profile", "default", "--sql", "SELECT 1", "--database", "OtherDB"],
|
|
82
|
+
conn_factory=factory,
|
|
83
|
+
)
|
|
84
|
+
assert captured["db"] == "OtherDB" # overrode the profile's "d"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# --- connection kwargs ------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
def test_connection_kwargs_basic():
|
|
90
|
+
profile = {"host": "h", "database": "d", "username": "u", "port": 3307}
|
|
91
|
+
k = connection.connection_kwargs(profile, "secret")
|
|
92
|
+
assert k["host"] == "h"
|
|
93
|
+
assert k["port"] == 3307
|
|
94
|
+
assert k["user"] == "u"
|
|
95
|
+
assert k["password"] == "secret"
|
|
96
|
+
assert k["database"] == "d"
|
|
97
|
+
assert k["autocommit"] is True
|
|
98
|
+
assert "ssl" not in k # tls off by default
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_connection_kwargs_tls_no_verify():
|
|
102
|
+
profile = {"host": "h", "tls": True, "tls_verify_cert": False}
|
|
103
|
+
k = connection.connection_kwargs(profile, "x")
|
|
104
|
+
ctx = k["ssl"]
|
|
105
|
+
assert ctx.check_hostname is False
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_masked_dsn_hides_password():
|
|
109
|
+
profile = {"host": "h", "database": "d", "username": "u"}
|
|
110
|
+
masked = connection.masked_dsn(profile)
|
|
111
|
+
assert ":***@" in masked
|
|
112
|
+
assert "mysql://u:***@h:3306/d" in masked
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# --- run_query: %s placeholders, dict rows, coercion ------------------------
|
|
116
|
+
|
|
117
|
+
def test_run_query_binds_params_and_coerces():
|
|
118
|
+
cur = FakeCursor(
|
|
119
|
+
description=[("id", None), ("ts", None), ("amt", None)],
|
|
120
|
+
rows=[{"id": 1, "ts": dt.datetime(2026, 1, 1), "amt": decimal.Decimal("9.99")}],
|
|
121
|
+
)
|
|
122
|
+
out = connection.run_query(FakeConn([cur]),
|
|
123
|
+
"SELECT * FROM t WHERE id = %s", [1], None)
|
|
124
|
+
assert cur.executed == [("SELECT * FROM t WHERE id = %s", [1])]
|
|
125
|
+
assert out["rows"][0]["ts"] == "2026-01-01T00:00:00"
|
|
126
|
+
assert out["rows"][0]["amt"] == "9.99"
|
|
127
|
+
assert out["truncated"] is False
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_run_query_truncates():
|
|
131
|
+
cur = FakeCursor(description=[("n", None)],
|
|
132
|
+
rows=[{"n": i} for i in range(5)])
|
|
133
|
+
out = connection.run_query(FakeConn([cur]), "SELECT n FROM t", None, 2)
|
|
134
|
+
assert out["row_count"] == 2
|
|
135
|
+
assert out["truncated"] is True
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# --- dispatch ---------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
def test_dispatch_query_read_only_ok(one_profile):
|
|
141
|
+
cur = FakeCursor(description=[("c", None)], rows=[{"c": 7}])
|
|
142
|
+
factory, conn = _factory(cur)
|
|
143
|
+
result = main.dispatch(
|
|
144
|
+
"query", ["--profile", "default", "--sql", "SELECT c FROM t"],
|
|
145
|
+
conn_factory=factory,
|
|
146
|
+
)
|
|
147
|
+
assert result["rows"] == [{"c": 7}]
|
|
148
|
+
assert result["write"] is False
|
|
149
|
+
assert conn.closed is True
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_dispatch_query_blocks_replace_upsert(one_profile):
|
|
153
|
+
# REPLACE is MySQL's upsert; the guard must block it read-only.
|
|
154
|
+
cur = FakeCursor(description=[], rows=[])
|
|
155
|
+
factory, _ = _factory(cur)
|
|
156
|
+
with pytest.raises(dbquery.WriteGuardError):
|
|
157
|
+
main.dispatch(
|
|
158
|
+
"query", ["--profile", "default", "--sql", "REPLACE INTO t VALUES (1)"],
|
|
159
|
+
conn_factory=factory,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def test_dispatch_query_allows_write_flag(one_profile):
|
|
164
|
+
cur = FakeCursor(description=[], rows=[])
|
|
165
|
+
factory, _ = _factory(cur)
|
|
166
|
+
result = main.dispatch(
|
|
167
|
+
"query",
|
|
168
|
+
["--profile", "default", "--sql", "DELETE FROM t WHERE id=%s",
|
|
169
|
+
"--params", "[1]", "--write"],
|
|
170
|
+
conn_factory=factory,
|
|
171
|
+
)
|
|
172
|
+
assert result["write"] is True
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_dispatch_tables_default_database(one_profile):
|
|
176
|
+
cur = FakeCursor(description=[("TABLE_NAME", None)], rows=[{"TABLE_NAME": "issues"}])
|
|
177
|
+
factory, _ = _factory(cur)
|
|
178
|
+
result = main.dispatch("tables", ["--profile", "default"], conn_factory=factory)
|
|
179
|
+
sql, params = cur.executed[0]
|
|
180
|
+
assert "DATABASE()" in sql # falls back to profile db
|
|
181
|
+
assert result["tables"][0]["TABLE_NAME"] == "issues"
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def test_dispatch_columns_parameterised(one_profile):
|
|
185
|
+
cur = FakeCursor(description=[("COLUMN_NAME", None)], rows=[{"COLUMN_NAME": "id"}])
|
|
186
|
+
factory, _ = _factory(cur)
|
|
187
|
+
main.dispatch("columns", ["--profile", "default", "--table", "redmine.issues"],
|
|
188
|
+
conn_factory=factory)
|
|
189
|
+
sql, params = cur.executed[0]
|
|
190
|
+
assert "%s" in sql
|
|
191
|
+
assert params == ["issues", "redmine"]
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def test_dispatch_unknown_action():
|
|
195
|
+
with pytest.raises(main.UsageError):
|
|
196
|
+
main.dispatch("nope", [])
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def test_dispatch_missing_required_arg():
|
|
200
|
+
with pytest.raises(main.UsageError):
|
|
201
|
+
main.dispatch("query", ["--profile", "default"]) # no --sql
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"""schema-extract / schema-diff / migrate tests for the mysql tool.
|
|
2
|
+
|
|
3
|
+
No live DB, no pymysql socket: a scripted fake connection answers the
|
|
4
|
+
INFORMATION_SCHEMA enumeration + SHOW CREATE / tracking-table queries by
|
|
5
|
+
matching on a substring of the SQL. Mirror writes go to tmp_path.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
from tools._lib import dbschema
|
|
15
|
+
from tools.mysql import main, schema
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# --- scripted fake DB-API (DictCursor: rows are dicts) ----------------------
|
|
19
|
+
|
|
20
|
+
class FakeCursor:
|
|
21
|
+
def __init__(self, conn):
|
|
22
|
+
self.conn = conn
|
|
23
|
+
self._result: list[dict] = []
|
|
24
|
+
self.closed = False
|
|
25
|
+
|
|
26
|
+
def execute(self, sql, params=None):
|
|
27
|
+
self.conn.executed.append((sql, list(params) if params else None))
|
|
28
|
+
self._result = self.conn._answer(sql, params)
|
|
29
|
+
|
|
30
|
+
def fetchall(self):
|
|
31
|
+
return list(self._result)
|
|
32
|
+
|
|
33
|
+
def fetchone(self):
|
|
34
|
+
return self._result[0] if self._result else None
|
|
35
|
+
|
|
36
|
+
def close(self):
|
|
37
|
+
self.closed = True
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class FakeConn:
|
|
41
|
+
"""Answers queries by scanning ``rules`` (substring -> rows or callable)."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, rules):
|
|
44
|
+
self.rules = rules
|
|
45
|
+
self.executed: list[tuple] = []
|
|
46
|
+
self.began = 0
|
|
47
|
+
self.committed = 0
|
|
48
|
+
self.rolled_back = 0
|
|
49
|
+
self.closed = False
|
|
50
|
+
|
|
51
|
+
def _answer(self, sql, params):
|
|
52
|
+
for needle, value in self.rules:
|
|
53
|
+
if needle in sql:
|
|
54
|
+
return value(params) if callable(value) else list(value)
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
def cursor(self):
|
|
58
|
+
return FakeCursor(self)
|
|
59
|
+
|
|
60
|
+
def begin(self):
|
|
61
|
+
self.began += 1
|
|
62
|
+
|
|
63
|
+
def commit(self):
|
|
64
|
+
self.committed += 1
|
|
65
|
+
|
|
66
|
+
def rollback(self):
|
|
67
|
+
self.rolled_back += 1
|
|
68
|
+
|
|
69
|
+
def close(self):
|
|
70
|
+
self.closed = True
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# --- extract_objects --------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
def _extract_rules():
|
|
76
|
+
return [
|
|
77
|
+
("SELECT DATABASE()", [{"db": "redmine"}]),
|
|
78
|
+
("TABLE_TYPE = %s",
|
|
79
|
+
lambda p: ([{"TABLE_NAME": "issues"}] if p and p[-1] == "BASE TABLE"
|
|
80
|
+
else [{"TABLE_NAME": "v_open"}] if p and p[-1] == "VIEW" else [])),
|
|
81
|
+
("ROUTINE_TYPE = %s",
|
|
82
|
+
lambda p: ([{"ROUTINE_NAME": "do_thing"}] if p and p[-1] == "PROCEDURE"
|
|
83
|
+
else [{"ROUTINE_NAME": "calc"}] if p and p[-1] == "FUNCTION" else [])),
|
|
84
|
+
("INFORMATION_SCHEMA.TRIGGERS", [{"TRIGGER_NAME": "trg_ins"}]),
|
|
85
|
+
("INFORMATION_SCHEMA.EVENTS", [{"EVENT_NAME": "nightly"}]),
|
|
86
|
+
("SHOW CREATE TABLE", [{"Table": "issues", "Create Table": "CREATE TABLE `issues` (\n id int\n)"}]),
|
|
87
|
+
("SHOW CREATE VIEW", [{"View": "v_open", "Create View": "CREATE VIEW `v_open` AS SELECT 1"}]),
|
|
88
|
+
("SHOW CREATE PROCEDURE", [{"Procedure": "do_thing", "Create Procedure": "CREATE PROCEDURE do_thing() BEGIN END"}]),
|
|
89
|
+
("SHOW CREATE FUNCTION", [{"Function": "calc", "Create Function": "CREATE FUNCTION calc() RETURNS INT RETURN 1"}]),
|
|
90
|
+
("SHOW CREATE TRIGGER", [{"Trigger": "trg_ins", "SQL Original Statement": "CREATE TRIGGER trg_ins BEFORE INSERT ON issues FOR EACH ROW SET @x=1"}]),
|
|
91
|
+
("SHOW CREATE EVENT", [{"Event": "nightly", "Create Event": "CREATE EVENT nightly ON SCHEDULE EVERY 1 DAY DO SELECT 1"}]),
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_extract_objects_all_types():
|
|
96
|
+
conn = FakeConn(_extract_rules())
|
|
97
|
+
records = schema.extract_objects(conn)
|
|
98
|
+
by_type = {r["type"]: r for r in records}
|
|
99
|
+
assert set(by_type) == {"Tables", "Views", "Procedures", "Functions",
|
|
100
|
+
"Triggers", "Events"}
|
|
101
|
+
assert by_type["Tables"]["name"] == "issues"
|
|
102
|
+
assert by_type["Tables"]["schema"] == "redmine"
|
|
103
|
+
assert by_type["Tables"]["definition"].startswith("CREATE TABLE `issues`")
|
|
104
|
+
# trigger uses the 'SQL Original Statement' key
|
|
105
|
+
assert by_type["Triggers"]["definition"].startswith("CREATE TRIGGER trg_ins")
|
|
106
|
+
# definitions are LF-normalized and newline-terminated
|
|
107
|
+
for r in records:
|
|
108
|
+
assert "\r" not in r["definition"]
|
|
109
|
+
assert r["definition"].endswith("\n")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_extract_objects_types_filter():
|
|
113
|
+
conn = FakeConn(_extract_rules())
|
|
114
|
+
records = schema.extract_objects(conn, types="TABLE,VIEW")
|
|
115
|
+
assert {r["type"] for r in records} == {"Tables", "Views"}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_create_value_falls_back_case_insensitive():
|
|
119
|
+
# MariaDB casing variant: 'create table' lowercase key
|
|
120
|
+
assert schema._create_value({"Table": "t", "create table": "CREATE TABLE t"},
|
|
121
|
+
"Create Table") == "CREATE TABLE t"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# --- schema-extract dispatch (conn_factory injection -> tmp_path) -----------
|
|
125
|
+
|
|
126
|
+
@pytest.fixture
|
|
127
|
+
def one_profile(tmp_path, monkeypatch):
|
|
128
|
+
from tools._lib import dbprofiles
|
|
129
|
+
pfile = tmp_path / "profiles.json"
|
|
130
|
+
monkeypatch.setattr(main, "PROFILES_PATH", pfile)
|
|
131
|
+
monkeypatch.setattr(dbprofiles.creds, "has", lambda *a: False)
|
|
132
|
+
monkeypatch.setattr(dbprofiles.creds, "get_optional", lambda *a: None)
|
|
133
|
+
main._store().add("default", {"host": "h", "database": "d", "username": "u"})
|
|
134
|
+
return pfile
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_schema_extract_dispatch_writes_mirror(one_profile, tmp_path):
|
|
138
|
+
out = tmp_path / "mirror"
|
|
139
|
+
conn = FakeConn(_extract_rules())
|
|
140
|
+
result = main.dispatch(
|
|
141
|
+
"schema-extract",
|
|
142
|
+
["--profile", "default", "--out", str(out)],
|
|
143
|
+
conn_factory=lambda _p: conn,
|
|
144
|
+
)
|
|
145
|
+
assert result["written"] == 6
|
|
146
|
+
assert result["total"] == 6
|
|
147
|
+
assert result["by_type"]["Tables"] == 1
|
|
148
|
+
# files on disk + manifest
|
|
149
|
+
assert (out / "schema" / "Tables" / "redmine.issues.sql").is_file()
|
|
150
|
+
manifest = json.loads((out / "_manifest.json").read_text(encoding="utf-8"))
|
|
151
|
+
assert any("issues" in rel for rel in manifest)
|
|
152
|
+
assert conn.closed is True
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_schema_extract_dry_run_writes_nothing(one_profile, tmp_path):
|
|
156
|
+
out = tmp_path / "mirror"
|
|
157
|
+
conn = FakeConn(_extract_rules())
|
|
158
|
+
result = main.dispatch(
|
|
159
|
+
"schema-extract",
|
|
160
|
+
["--profile", "default", "--out", str(out), "--dry-run"],
|
|
161
|
+
conn_factory=lambda _p: conn,
|
|
162
|
+
)
|
|
163
|
+
assert result["dry_run"] is True
|
|
164
|
+
assert result["written"] == 6
|
|
165
|
+
assert not out.exists() # nothing written to disk
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_schema_extract_incremental_second_run(one_profile, tmp_path):
|
|
169
|
+
out = tmp_path / "mirror"
|
|
170
|
+
main.dispatch("schema-extract", ["--profile", "default", "--out", str(out)],
|
|
171
|
+
conn_factory=lambda _p: FakeConn(_extract_rules()))
|
|
172
|
+
# second run, identical objects -> nothing written
|
|
173
|
+
result = main.dispatch("schema-extract", ["--profile", "default", "--out", str(out)],
|
|
174
|
+
conn_factory=lambda _p: FakeConn(_extract_rules()))
|
|
175
|
+
assert result["written"] == 0
|
|
176
|
+
assert result["unchanged"] == 6
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# --- schema-diff dir-vs-dir (no DB) ----------------------------------------
|
|
180
|
+
|
|
181
|
+
def _make_mirror(root: Path, files: dict[str, str]):
|
|
182
|
+
for rel, text in files.items():
|
|
183
|
+
p = root / "schema" / rel
|
|
184
|
+
p.parent.mkdir(parents=True, exist_ok=True)
|
|
185
|
+
p.write_text(text, encoding="utf-8")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def test_schema_diff_dir_vs_dir(tmp_path):
|
|
189
|
+
left = tmp_path / "L"
|
|
190
|
+
right = tmp_path / "R"
|
|
191
|
+
_make_mirror(left, {"Tables/a.sql": "CREATE TABLE a (id int);\n",
|
|
192
|
+
"Tables/gone.sql": "CREATE TABLE gone (id int);\n"})
|
|
193
|
+
_make_mirror(right, {"Tables/a.sql": "CREATE TABLE a (id bigint);\n",
|
|
194
|
+
"Tables/new.sql": "CREATE TABLE new (id int);\n"})
|
|
195
|
+
result = main.dispatch("schema-diff", ["--left", str(left), "--right", str(right)])
|
|
196
|
+
assert result["summary"] == {"added": 1, "removed": 1, "changed": 1}
|
|
197
|
+
assert result["added"] == ["schema/Tables/new.sql"]
|
|
198
|
+
assert result["removed"] == ["schema/Tables/gone.sql"]
|
|
199
|
+
assert "bigint" in result["changed"][0]["diff"]
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def test_schema_diff_no_diff_text(tmp_path):
|
|
203
|
+
left = tmp_path / "L"
|
|
204
|
+
right = tmp_path / "R"
|
|
205
|
+
_make_mirror(left, {"Tables/a.sql": "x\n"})
|
|
206
|
+
_make_mirror(right, {"Tables/a.sql": "y\n"})
|
|
207
|
+
result = main.dispatch(
|
|
208
|
+
"schema-diff",
|
|
209
|
+
["--left", str(left), "--right", str(right), "--no-diff-text"])
|
|
210
|
+
assert result["summary"]["changed"] == 1
|
|
211
|
+
assert "diff" not in result["changed"][0]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def test_schema_diff_rejects_bad_dir(tmp_path):
|
|
215
|
+
left = tmp_path / "L"
|
|
216
|
+
_make_mirror(left, {"Tables/a.sql": "x\n"})
|
|
217
|
+
with pytest.raises(main.UsageError):
|
|
218
|
+
main.dispatch("schema-diff",
|
|
219
|
+
["--left", str(left), "--right", str(tmp_path / "nope")])
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# --- migrate: list + apply gating -------------------------------------------
|
|
223
|
+
|
|
224
|
+
def _migrations_dir(tmp_path: Path) -> Path:
|
|
225
|
+
d = tmp_path / "migs"
|
|
226
|
+
d.mkdir()
|
|
227
|
+
(d / "0001_create_t.sql").write_text("CREATE TABLE t (id int);\n", encoding="utf-8")
|
|
228
|
+
(d / "0002_drop_t.sql").write_text("DROP TABLE t;\n", encoding="utf-8")
|
|
229
|
+
return d
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _migrate_rules(applied_rows):
|
|
233
|
+
return [
|
|
234
|
+
("information_schema.tables", [{"x": 1}]), # tracking_table_exists -> exists
|
|
235
|
+
("CREATE TABLE IF NOT EXISTS", []), # ensure_migrations_table (apply only)
|
|
236
|
+
(f"FROM `{schema.MIGRATIONS_TABLE}`", applied_rows), # fetch_applied
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def test_migrate_list_pending_and_drift(one_profile, tmp_path):
|
|
241
|
+
d = _migrations_dir(tmp_path)
|
|
242
|
+
# 0001 already applied, but with a STALE sha -> drift
|
|
243
|
+
applied = [{"migration_id": "0001_create_t", "filename": "0001_create_t.sql",
|
|
244
|
+
"sha256": "deadbeef", "applied_at": None}]
|
|
245
|
+
conn = FakeConn(_migrate_rules(applied))
|
|
246
|
+
result = main.dispatch(
|
|
247
|
+
"migrate",
|
|
248
|
+
["--profile", "default", "--dir", str(d), "--mode", "list"],
|
|
249
|
+
conn_factory=lambda _p: conn,
|
|
250
|
+
)
|
|
251
|
+
assert result["applied_count"] == 1
|
|
252
|
+
assert result["pending_count"] == 1
|
|
253
|
+
assert result["pending"][0]["migration_id"] == "0002_drop_t"
|
|
254
|
+
# 0002 drops a table -> danger warning surfaced
|
|
255
|
+
assert any("DROP" in w for w in result["pending"][0]["danger_warnings"])
|
|
256
|
+
assert result["drift"] == ["0001_create_t"]
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def test_migrate_list_is_read_only_when_table_absent(one_profile, tmp_path):
|
|
260
|
+
"""`list` must NEVER create the tracking table (read-only on production DBs)."""
|
|
261
|
+
d = _migrations_dir(tmp_path)
|
|
262
|
+
conn = FakeConn([("information_schema.tables", [])]) # tracking table absent
|
|
263
|
+
result = main.dispatch(
|
|
264
|
+
"migrate", ["--profile", "default", "--dir", str(d), "--mode", "list"],
|
|
265
|
+
conn_factory=lambda _p: conn)
|
|
266
|
+
assert result["applied_count"] == 0 and result["pending_count"] == 2
|
|
267
|
+
assert not any("CREATE TABLE" in sql.upper() for sql, _ in conn.executed)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def test_migrate_apply_requires_apply_flag(one_profile, tmp_path):
|
|
271
|
+
d = _migrations_dir(tmp_path)
|
|
272
|
+
conn = FakeConn(_migrate_rules([]))
|
|
273
|
+
with pytest.raises(main.UsageError) as ei:
|
|
274
|
+
main.dispatch(
|
|
275
|
+
"migrate",
|
|
276
|
+
["--profile", "default", "--dir", str(d), "--mode", "apply"],
|
|
277
|
+
conn_factory=lambda _p: conn,
|
|
278
|
+
)
|
|
279
|
+
assert "--apply" in str(ei.value)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def test_migrate_apply_runs_pending_and_records(one_profile, tmp_path):
|
|
283
|
+
d = _migrations_dir(tmp_path)
|
|
284
|
+
conn = FakeConn(_migrate_rules([]))
|
|
285
|
+
result = main.dispatch(
|
|
286
|
+
"migrate",
|
|
287
|
+
["--profile", "default", "--dir", str(d), "--mode", "apply", "--apply"],
|
|
288
|
+
conn_factory=lambda _p: conn,
|
|
289
|
+
)
|
|
290
|
+
statuses = [r["status"] for r in result["applied_results"]]
|
|
291
|
+
assert statuses == ["applied", "applied"]
|
|
292
|
+
# two files applied -> two transactions committed + two tracking inserts
|
|
293
|
+
assert conn.committed == 2
|
|
294
|
+
inserts = [s for s, _ in conn.executed if "INSERT INTO" in s and schema.MIGRATIONS_TABLE in s]
|
|
295
|
+
assert len(inserts) == 2
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def test_migrate_apply_dry_run_rolls_back(one_profile, tmp_path):
|
|
299
|
+
d = _migrations_dir(tmp_path)
|
|
300
|
+
conn = FakeConn(_migrate_rules([]))
|
|
301
|
+
result = main.dispatch(
|
|
302
|
+
"migrate",
|
|
303
|
+
["--profile", "default", "--dir", str(d), "--mode", "apply",
|
|
304
|
+
"--apply", "--dry-run"],
|
|
305
|
+
conn_factory=lambda _p: conn,
|
|
306
|
+
)
|
|
307
|
+
assert all(r["status"] == "dry-run" for r in result["applied_results"])
|
|
308
|
+
assert conn.rolled_back == 2
|
|
309
|
+
assert conn.committed == 0
|
|
310
|
+
# no tracking inserts on dry-run
|
|
311
|
+
assert not any("INSERT INTO" in s and schema.MIGRATIONS_TABLE in s
|
|
312
|
+
for s, _ in conn.executed)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def test_migrate_apply_refuses_on_drift(one_profile, tmp_path):
|
|
316
|
+
d = _migrations_dir(tmp_path)
|
|
317
|
+
applied = [{"migration_id": "0001_create_t", "filename": "0001_create_t.sql",
|
|
318
|
+
"sha256": "stale", "applied_at": None}]
|
|
319
|
+
conn = FakeConn(_migrate_rules(applied))
|
|
320
|
+
with pytest.raises(main.UsageError) as ei:
|
|
321
|
+
main.dispatch(
|
|
322
|
+
"migrate",
|
|
323
|
+
["--profile", "default", "--dir", str(d), "--mode", "apply", "--apply"],
|
|
324
|
+
conn_factory=lambda _p: conn,
|
|
325
|
+
)
|
|
326
|
+
assert "drift" in str(ei.value).lower()
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
# --- shared dbschema migration helpers (sanity, no DB) ----------------------
|
|
330
|
+
|
|
331
|
+
def test_discover_and_pending(tmp_path):
|
|
332
|
+
d = _migrations_dir(tmp_path)
|
|
333
|
+
found, skipped = dbschema.discover_migrations(d)
|
|
334
|
+
assert [mid for mid, _ in found] == ["0001_create_t", "0002_drop_t"]
|
|
335
|
+
assert skipped == []
|
|
336
|
+
pend = dbschema.pending({"0001_create_t"}, found)
|
|
337
|
+
assert [mid for mid, _ in pend] == ["0002_drop_t"]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
name: mysql
|
|
2
|
+
description: Read-only MySQL/MariaDB queries over pymysql with named connection profiles. SELECT-only by default (--write to override); returns rows as JSON; schema/table introspection. MySQL has no read-only intent, so the write-guard is the enforcement.
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
runtime: python
|
|
5
|
+
entrypoint: main.py
|
|
6
|
+
|
|
7
|
+
# Secrets are PER-PROFILE and dynamic, so none are declared here.
|
|
8
|
+
# Each profile's password lives in Windows Credential Manager under
|
|
9
|
+
# agents-and-tools:mysql:<profile-name> and is read at runtime via
|
|
10
|
+
# tools._lib.creds.get("mysql", <profile>). Set one with:
|
|
11
|
+
# python scripts/set-credential.py mysql <profile>
|
|
12
|
+
# Non-secret profile config (host/database/username/port/charset/tls) lives in
|
|
13
|
+
# this tool's profiles.json — never the password.
|
|
14
|
+
secrets: []
|
|
15
|
+
|
|
16
|
+
routing:
|
|
17
|
+
triggers:
|
|
18
|
+
- run a MySQL query
|
|
19
|
+
- query a MySQL / MariaDB database
|
|
20
|
+
- read a table from MySQL
|
|
21
|
+
- list MySQL tables or columns
|
|
22
|
+
primary_action: query
|
|
23
|
+
example: mysql query --profile default --sql "SELECT * FROM issues LIMIT 10"
|
|
24
|
+
|
|
25
|
+
actions:
|
|
26
|
+
- name: profiles
|
|
27
|
+
description: List configured connection profiles (no passwords).
|
|
28
|
+
args: []
|
|
29
|
+
output_schema: '{ "count": N, "profiles": [ {name, host, database, ..., has_password} ] }'
|
|
30
|
+
|
|
31
|
+
- name: add-profile
|
|
32
|
+
description: Store a connection profile (config only; set the password separately via set-credential).
|
|
33
|
+
args:
|
|
34
|
+
- {name: name, type: string, required: true, description: Profile name (also the credential name)}
|
|
35
|
+
- {name: host, type: string, required: true, description: MySQL host}
|
|
36
|
+
- {name: database, type: string, description: Default schema/database}
|
|
37
|
+
- {name: username, type: string, description: MySQL user (default root)}
|
|
38
|
+
- {name: port, type: integer, description: TCP port (default 3306)}
|
|
39
|
+
- {name: charset, type: string, description: Connection charset (default utf8mb4)}
|
|
40
|
+
- {name: tls, type: string, description: Wrap the socket in TLS - yes or no (default no)}
|
|
41
|
+
- {name: tls-verify-cert, type: string, description: Verify the server cert chain - yes or no (default no)}
|
|
42
|
+
- {name: connect-timeout, type: integer, description: Connect timeout seconds (default 30)}
|
|
43
|
+
- {name: statement-timeout, type: integer, description: "Read/statement timeout seconds, 0=unbounded (default 300)"}
|
|
44
|
+
- {name: overwrite, type: boolean, description: Replace an existing profile}
|
|
45
|
+
output_schema: '{ "name": "...", "host": "...", "has_password": false, "note": "..." }'
|
|
46
|
+
|
|
47
|
+
- name: test-connection
|
|
48
|
+
description: Connect and return the masked connection string + server version (never the password).
|
|
49
|
+
args:
|
|
50
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
51
|
+
output_schema: '{ "profile": "...", "connection_string": "mysql://user:***@host...", "server_version": "...", "connected": true }'
|
|
52
|
+
|
|
53
|
+
- name: query
|
|
54
|
+
description: Run read-only SQL (SELECT by default; --write allows non-SELECT). Params bound via %s placeholders, never interpolated.
|
|
55
|
+
args:
|
|
56
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
57
|
+
- {name: sql, type: string, required: true, description: SQL statement}
|
|
58
|
+
- {name: params, type: string, description: "Parameter values as a JSON array, bound via %s placeholders"}
|
|
59
|
+
- {name: max-rows, type: integer, description: Cap rows returned (default 1000; 0=unbounded)}
|
|
60
|
+
- {name: write, type: boolean, description: Allow a non-SELECT/DDL/multi statement (off by default)}
|
|
61
|
+
- {name: database, type: string, description: Run against this database instead of the profile's}
|
|
62
|
+
output_schema: '{ "columns": [...], "rows": [ {...} ], "row_count": N, "truncated": false, "write": false }'
|
|
63
|
+
|
|
64
|
+
- name: tables
|
|
65
|
+
description: List tables and views, optionally restricted to one schema.
|
|
66
|
+
args:
|
|
67
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
68
|
+
- {name: database, type: string, description: List tables from this database instead of the profile's}
|
|
69
|
+
- {name: schema, type: string, description: Restrict to one schema (default the profile's database)}
|
|
70
|
+
output_schema: '{ "profile": "...", "count": N, "tables": [ {TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE} ] }'
|
|
71
|
+
|
|
72
|
+
- name: columns
|
|
73
|
+
description: List a table's columns (name, type, nullable, key, length, default).
|
|
74
|
+
args:
|
|
75
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
76
|
+
- {name: database, type: string, description: Read columns from this database instead of the profile's}
|
|
77
|
+
- {name: table, type: string, required: true, description: Table name (schema.table or table)}
|
|
78
|
+
output_schema: '{ "profile": "...", "table": "...", "count": N, "columns": [ {COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY, ...} ] }'
|
|
79
|
+
|
|
80
|
+
- name: schema-extract
|
|
81
|
+
description: "Mirror every object in the database to local .sql files (one per object) under <out>/schema/<Type>/. Read-only and incremental: a re-run with no changes writes nothing."
|
|
82
|
+
args:
|
|
83
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
84
|
+
- {name: database, type: string, description: Extract this database instead of the profile's}
|
|
85
|
+
- {name: out, type: string, description: "Mirror output directory (default ./db-mirror/<profile>)"}
|
|
86
|
+
- {name: types, type: string, description: "Comma list of object types to include: TABLE,VIEW,PROCEDURE,FUNCTION,TRIGGER,EVENT (default all)"}
|
|
87
|
+
- {name: full, type: boolean, description: "Wipe and re-extract everything (default: incremental)"}
|
|
88
|
+
- {name: dry-run, type: boolean, description: Report what would change without writing}
|
|
89
|
+
output_schema: '{ "profile": "...", "database": "...", "out": "...", "written": N, "unchanged": N, "removed": N, "total": N, "by_type": {}, "dry_run": false }'
|
|
90
|
+
|
|
91
|
+
- name: schema-diff
|
|
92
|
+
description: "Compare two schema sides and report objects added/removed/changed with a unified diff per change. Each side is a mirror directory OR profile:NAME (extracted live to a temp mirror). Read-only end to end."
|
|
93
|
+
args:
|
|
94
|
+
- {name: left, type: string, required: true, description: "A mirror directory OR profile:NAME to extract live"}
|
|
95
|
+
- {name: right, type: string, required: true, description: "A mirror directory OR profile:NAME to extract live"}
|
|
96
|
+
- {name: database-left, type: string, description: "DB override when --left is a profile"}
|
|
97
|
+
- {name: database-right, type: string, description: "DB override when --right is a profile"}
|
|
98
|
+
- {name: types, type: string, description: "Comma list of object types to include when a side is a profile"}
|
|
99
|
+
- {name: no-diff-text, type: boolean, description: "Suppress per-object unified diff bodies (name lists only)"}
|
|
100
|
+
output_schema: '{ "left": "...", "right": "...", "added": [], "removed": [], "changed": [ {relpath, diff} ], "unchanged": N, "identical": false, "summary": {added, removed, changed} }'
|
|
101
|
+
|
|
102
|
+
- name: migrate
|
|
103
|
+
description: "Forward-only versioned migration runner. mode=list (default, read-only) shows applied/pending + drift + danger warnings; mode=apply (gated by --apply) runs pending in order, recording each in __schema_migrations. --dry-run wraps each in a rolled-back transaction. DELIMITER caveat: each file runs as a single statement."
|
|
104
|
+
args:
|
|
105
|
+
- {name: profile, type: string, required: true, description: Profile name}
|
|
106
|
+
- {name: database, type: string, description: Migrate this database instead of the profile's}
|
|
107
|
+
- {name: dir, type: string, description: "Migrations directory (default ./db-migrations/<profile>)"}
|
|
108
|
+
- {name: mode, type: string, description: "list (read-only, default) or apply (writes)"}
|
|
109
|
+
- {name: dry-run, type: boolean, description: Apply each pending migration in a rolled-back transaction}
|
|
110
|
+
- {name: apply, type: boolean, description: "Required confirmation to actually write (with --mode apply)"}
|
|
111
|
+
- {name: accept-drift, type: boolean, description: Proceed with apply even if applied files changed on disk}
|
|
112
|
+
output_schema: '{ "profile": "...", "database": "...", "dir": "...", "mode": "list", "applied_count": N, "pending": [ {migration_id, filename, sha256, danger_warnings} ], "drift": [], "applied_results": [] }'
|