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,96 @@
|
|
|
1
|
+
"""`<component>-edit --dry-run` must preview the EDIT, not a create.
|
|
2
|
+
|
|
3
|
+
The bug: the dry-run branch called `build_dto` straight from the loaded config, skipping the
|
|
4
|
+
component's own edit preparation. For a process that preparation is what reuses the live flow's
|
|
5
|
+
VARIABLE IDS by name and its canvas positions — so the preview showed brand-new variable ids while
|
|
6
|
+
the real edit would have kept them.
|
|
7
|
+
|
|
8
|
+
That is the worst possible direction for a preview to be wrong. A process variable is referenced by
|
|
9
|
+
GUID from outside the process (a form's RUN_PROCESS inputMap/outputMap binds it by id), so "do the
|
|
10
|
+
ids change?" is exactly the question a dry-run is run to answer, and it answered it wrongly in both
|
|
11
|
+
directions: a preserved id shown as changed, and — for a config that renames a variable — a change
|
|
12
|
+
shown as if nothing external would break.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
|
|
18
|
+
from tools.procesio.dto import framework
|
|
19
|
+
from tools.procesio.dto.process import builder as process_builder
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
LIVE_VAR_ID = "11111111-1111-1111-1111-111111111111"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _Client:
|
|
26
|
+
"""Serves one live flow, the way GET /api/Projects/{id} does."""
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
self.gets = []
|
|
30
|
+
|
|
31
|
+
def get(self, path, query=None):
|
|
32
|
+
self.gets.append(path)
|
|
33
|
+
return {"flow": {"id": "flow-1", "title": "P", "actions": [],
|
|
34
|
+
"variables": [{"id": LIVE_VAR_ID, "name": "Row", "isError": False}]}}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _component(calls: list) -> framework.Component:
|
|
38
|
+
"""A minimal component whose build simply reports the ctx it was handed."""
|
|
39
|
+
def build(config, ctx):
|
|
40
|
+
calls.append(ctx)
|
|
41
|
+
return {"Variables": [{"Name": "Row",
|
|
42
|
+
"Id": (ctx.get("existing_var_ids") or {}).get("row", "NEW-ID")}]}
|
|
43
|
+
|
|
44
|
+
def edit_ctx(client, resource_id, config, ctx):
|
|
45
|
+
cur = client.get(f"/api/Projects/{resource_id}")
|
|
46
|
+
flow = cur.get("flow", cur)
|
|
47
|
+
return {**ctx, "existing_var_ids": {(v["name"] or "").strip().lower(): v["id"]
|
|
48
|
+
for v in flow.get("variables") or []}}
|
|
49
|
+
|
|
50
|
+
return framework.Component(
|
|
51
|
+
# the real process dir, so validate_config finds a schema; the config below satisfies it
|
|
52
|
+
name="process", description="", dir=process_builder.DIR,
|
|
53
|
+
build=build, create_endpoint=("POST", "/x"), get_path="/x/{id}",
|
|
54
|
+
extract_id=lambda r, d: None, edit_ctx=edit_ctx)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _args(**kw):
|
|
58
|
+
return argparse.Namespace(id="flow-1", config=None, config_file=None,
|
|
59
|
+
dry_run=True, force=False, no_types=False, **kw)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_the_dry_run_preview_reuses_the_live_variable_ids():
|
|
63
|
+
calls: list = []
|
|
64
|
+
comp = _component(calls)
|
|
65
|
+
client = _Client()
|
|
66
|
+
|
|
67
|
+
dto = framework.build_edit_dto(comp, client, "flow-1", {"title": "P"}, {})
|
|
68
|
+
|
|
69
|
+
assert dto["Variables"][0]["Id"] == LIVE_VAR_ID, (
|
|
70
|
+
"the preview must show the id the edit would actually write")
|
|
71
|
+
assert calls and calls[0].get("existing_var_ids") == {"row": LIVE_VAR_ID}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_a_component_without_an_edit_ctx_hook_is_unaffected():
|
|
75
|
+
calls: list = []
|
|
76
|
+
comp = _component(calls)
|
|
77
|
+
comp.edit_ctx = None
|
|
78
|
+
client = _Client()
|
|
79
|
+
|
|
80
|
+
dto = framework.build_edit_dto(comp, client, "flow-1", {"title": "P"}, {})
|
|
81
|
+
|
|
82
|
+
assert dto["Variables"][0]["Id"] == "NEW-ID"
|
|
83
|
+
assert client.gets == [], "no live read when the component has nothing to preserve"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_an_unreadable_live_resource_falls_back_to_a_plain_build():
|
|
87
|
+
"""A preview must still be produced when the live flow cannot be read."""
|
|
88
|
+
calls: list = []
|
|
89
|
+
comp = _component(calls)
|
|
90
|
+
|
|
91
|
+
class Broken(_Client):
|
|
92
|
+
def get(self, path, query=None):
|
|
93
|
+
raise RuntimeError("gone")
|
|
94
|
+
|
|
95
|
+
dto = framework.build_edit_dto(comp, Broken(), "flow-1", {"title": "P"}, {})
|
|
96
|
+
assert dto["Variables"][0]["Id"] == "NEW-ID"
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""Tests for the opt-in ELK 'layered' layout engine + the LAYOUT_ENGINE dispatch flag.
|
|
2
|
+
|
|
3
|
+
The ELK-runtime tests need Node + elkjs (tools/procesio/layout/elk/node_modules); they skip
|
|
4
|
+
if that toolchain is absent. The dispatch/flag and graceful-fallback tests are pure Python
|
|
5
|
+
and always run.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import copy
|
|
10
|
+
import math
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
from tools.procesio.layout import dispatch, elk_engine, engine
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _elk_available() -> bool:
|
|
18
|
+
"""True iff the REAL ELK runner works here — node on PATH, elkjs installed
|
|
19
|
+
(tools/procesio/layout/elk/node_modules), runner returns a laid-out graph.
|
|
20
|
+
|
|
21
|
+
Probe the runner DIRECTLY, never through elk_engine.layout(): layout() swallows every
|
|
22
|
+
ELK failure and returns the LEGACY layout, so any "did we get sane positions back"
|
|
23
|
+
check reports available on a machine with no node_modules. The skip then never fires
|
|
24
|
+
and the ELK-specific assertions below run against the legacy engine — which is exactly
|
|
25
|
+
how test_elk_long_straight_run_is_clustered failed on a fresh checkout while the other
|
|
26
|
+
four @requires_elk tests passed by coincidence.
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
graph = elk_engine._build_elk_graph(
|
|
30
|
+
[elk_engine._norm({"id": "a"}), elk_engine._norm({"id": "b"})],
|
|
31
|
+
[{"source": "a", "dest": "b"}])
|
|
32
|
+
return bool(elk_engine._run_elk(graph))
|
|
33
|
+
except Exception: # noqa: BLE001 — any failure means "not available", never a test error
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
requires_elk = pytest.mark.skipif(not _elk_available(),
|
|
38
|
+
reason="Node/elkjs runner unavailable")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _assert_all_finite(res, ids):
|
|
42
|
+
"""Every id has a position and no coordinate is NaN / None / non-finite."""
|
|
43
|
+
p = res["positions"]
|
|
44
|
+
for i in ids:
|
|
45
|
+
assert i in p, f"{i} missing a position"
|
|
46
|
+
for i, q in p.items():
|
|
47
|
+
assert q["x"] is not None and q["y"] is not None, f"{i} has a None coordinate"
|
|
48
|
+
assert isinstance(q["x"], float) and isinstance(q["y"], float), f"{i} non-float"
|
|
49
|
+
assert not math.isnan(q["x"]) and not math.isnan(q["y"]), f"{i} is NaN"
|
|
50
|
+
assert math.isfinite(q["x"]) and math.isfinite(q["y"]), f"{i} not finite"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# --- graph shapes ----------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
def _linear(n=6):
|
|
56
|
+
nodes = [{"id": f"n{i}"} for i in range(n)]
|
|
57
|
+
edges = [{"source": f"n{i}", "dest": f"n{i + 1}"} for i in range(n - 1)]
|
|
58
|
+
return nodes, edges
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _branching():
|
|
62
|
+
"""start -> a -> {b,c} -> d -> stop, with an error edge a->err and a d->a back-edge."""
|
|
63
|
+
nodes = [{"id": i} for i in ("start", "a", "b", "c", "d", "err", "stop")]
|
|
64
|
+
edges = [
|
|
65
|
+
{"source": "start", "dest": "a"}, {"source": "a", "dest": "b"},
|
|
66
|
+
{"source": "a", "dest": "c"}, {"source": "b", "dest": "d"},
|
|
67
|
+
{"source": "c", "dest": "d"}, {"source": "d", "dest": "stop"},
|
|
68
|
+
{"source": "a", "dest": "err", "type": 1},
|
|
69
|
+
{"source": "d", "dest": "a"}, # back-edge (loop / retry)
|
|
70
|
+
]
|
|
71
|
+
return nodes, edges
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _compound():
|
|
75
|
+
"""A For-Each container 'loop' holding an inner k1->k2 pipeline."""
|
|
76
|
+
nodes = [{"id": "start"}, {"id": "loop", "kind": "area"},
|
|
77
|
+
{"id": "k1", "parent_id": "loop"}, {"id": "k2", "parent_id": "loop"},
|
|
78
|
+
{"id": "stop"}]
|
|
79
|
+
edges = [{"source": "start", "dest": "loop"}, {"source": "loop", "dest": "k1"},
|
|
80
|
+
{"source": "k1", "dest": "k2"}, {"source": "loop", "dest": "stop"}]
|
|
81
|
+
return nodes, edges
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# --- ELK-runtime tests -----------------------------------------------------
|
|
85
|
+
|
|
86
|
+
@requires_elk
|
|
87
|
+
def test_elk_flat_linear_all_positioned():
|
|
88
|
+
nodes, edges = _linear()
|
|
89
|
+
res = elk_engine.layout(nodes, edges)
|
|
90
|
+
_assert_all_finite(res, [n["id"] for n in nodes])
|
|
91
|
+
p = res["positions"]
|
|
92
|
+
assert res["areas"] == {} # no containers in a flat graph
|
|
93
|
+
# readability config: a linear chain is ONE straight left-to-right row (wrapping OFF,
|
|
94
|
+
# Brandes-Köpf alignment) — every node on the same y, x strictly increasing.
|
|
95
|
+
assert len({round(q["y"]) for q in p.values()}) == 1 # single straight row
|
|
96
|
+
xs = [p[f"n{i}"]["x"] for i in range(len(nodes))]
|
|
97
|
+
assert xs == sorted(xs) and len(set(xs)) == len(nodes) # each node right of the previous
|
|
98
|
+
assert p["n0"]["x"] == min(q["x"] for q in p.values()) # starts at the left
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@requires_elk
|
|
102
|
+
def test_elk_short_straight_run_not_clustered():
|
|
103
|
+
# a 6-node chain is NOT longer than CLUSTER_MIN(6) → stays one straight left-to-right row
|
|
104
|
+
nodes = [{"id": f"n{i}"} for i in range(6)]
|
|
105
|
+
edges = [{"source": f"n{i}", "dest": f"n{i + 1}"} for i in range(5)]
|
|
106
|
+
p = elk_engine.layout(nodes, edges)["positions"]
|
|
107
|
+
assert len({round(v["y"]) for v in p.values()}) == 1 # single row (not folded)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@requires_elk
|
|
111
|
+
def test_elk_long_straight_run_is_clustered():
|
|
112
|
+
# an 8-node straight run (> CLUSTER_MIN) folds into a compact serpentine: fewer columns,
|
|
113
|
+
# more than one row, every node still placed and finite.
|
|
114
|
+
n = 8
|
|
115
|
+
nodes = [{"id": f"n{i}"} for i in range(n)]
|
|
116
|
+
edges = [{"source": f"n{i}", "dest": f"n{i + 1}"} for i in range(n - 1)]
|
|
117
|
+
res = elk_engine.layout(nodes, edges)
|
|
118
|
+
_assert_all_finite(res, [f"n{i}" for i in range(n)])
|
|
119
|
+
p = res["positions"]
|
|
120
|
+
assert len({round(v["y"]) for v in p.values()}) > 1 # folded into multiple rows
|
|
121
|
+
assert len({round(v["x"]) for v in p.values()}) < n # fewer columns than nodes
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@requires_elk
|
|
125
|
+
def test_elk_branching_all_positioned():
|
|
126
|
+
nodes, edges = _branching()
|
|
127
|
+
res = elk_engine.layout(nodes, edges)
|
|
128
|
+
_assert_all_finite(res, [n["id"] for n in nodes]) # cycle + error edge don't crash it
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@requires_elk
|
|
132
|
+
def test_elk_compound_children_inside_frame():
|
|
133
|
+
nodes, edges = _compound()
|
|
134
|
+
res = elk_engine.layout(nodes, edges)
|
|
135
|
+
_assert_all_finite(res, [n["id"] for n in nodes])
|
|
136
|
+
assert "loop" in res["areas"], "container must produce an area frame"
|
|
137
|
+
fr = res["areas"]["loop"]
|
|
138
|
+
for k in ("width", "height", "x", "y"):
|
|
139
|
+
assert math.isfinite(fr[k])
|
|
140
|
+
for kid in ("k1", "k2"): # children land inside the frame
|
|
141
|
+
q = res["positions"][kid]
|
|
142
|
+
assert fr["x"] <= q["x"] <= fr["x"] + fr["width"]
|
|
143
|
+
assert fr["y"] <= q["y"] <= fr["y"] + fr["height"]
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@requires_elk
|
|
147
|
+
def test_elk_deterministic():
|
|
148
|
+
nodes, edges = _branching()
|
|
149
|
+
a = elk_engine.layout(nodes, edges)
|
|
150
|
+
b = elk_engine.layout(copy.deepcopy(nodes), copy.deepcopy(edges))
|
|
151
|
+
assert a == b # fixed seed → identical output
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@requires_elk
|
|
155
|
+
def test_elk_missing_endpoint_is_dropped_not_crashed():
|
|
156
|
+
res = elk_engine.layout([{"id": "x"}, {"id": "y"}],
|
|
157
|
+
[{"source": "x", "dest": "GHOST"}, {"source": "x", "dest": "y"}])
|
|
158
|
+
_assert_all_finite(res, ["x", "y"]) # ghost edge ignored, nodes placed
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# --- resilience (engine-agnostic) ------------------------------------------
|
|
162
|
+
|
|
163
|
+
def test_elk_empty_graph():
|
|
164
|
+
res = elk_engine.layout([], [])
|
|
165
|
+
assert res["positions"] == {} and res["areas"] == {}
|
|
166
|
+
assert res["bbox"] == {"minX": 0, "minY": 0, "maxX": 0, "maxY": 0}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_elk_subset_delegates_to_legacy():
|
|
170
|
+
# partial re-tidy is legacy-only; the ELK engine must delegate and match legacy exactly.
|
|
171
|
+
nodes = [{"id": "a", "position": {"x": 0, "y": 100}},
|
|
172
|
+
{"id": "b", "position": {"x": 5000, "y": 9000}},
|
|
173
|
+
{"id": "c", "position": {"x": 520, "y": 100}}]
|
|
174
|
+
edges = [{"source": "a", "dest": "b"}, {"source": "b", "dest": "c"}]
|
|
175
|
+
assert elk_engine.layout(nodes, edges, subset=["b"]) == \
|
|
176
|
+
engine.layout(copy.deepcopy(nodes), copy.deepcopy(edges), subset=["b"])
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_elk_falls_back_to_legacy_on_runner_failure(monkeypatch):
|
|
180
|
+
# force the ELK invocation to fail; the engine must degrade to a valid legacy layout.
|
|
181
|
+
def boom(_graph):
|
|
182
|
+
raise RuntimeError("simulated: node not found")
|
|
183
|
+
monkeypatch.setattr(elk_engine, "_run_elk", boom)
|
|
184
|
+
nodes, edges = _linear()
|
|
185
|
+
res = elk_engine.layout(nodes, edges)
|
|
186
|
+
assert res == engine.layout(nodes, edges) # exactly the legacy result
|
|
187
|
+
_assert_all_finite(res, [n["id"] for n in nodes])
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# --- dispatch flag ---------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
def test_dispatch_defaults_to_legacy(monkeypatch):
|
|
193
|
+
monkeypatch.delenv("LAYOUT_ENGINE", raising=False)
|
|
194
|
+
assert dispatch.selected_engine() == "legacy"
|
|
195
|
+
nodes, edges = _linear()
|
|
196
|
+
assert dispatch.layout(nodes, edges) == engine.layout(nodes, edges)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@pytest.mark.parametrize("val", ["", " ", "bogus", "LEGACY", "ELKZ"])
|
|
200
|
+
def test_dispatch_invalid_or_unset_is_legacy(monkeypatch, val):
|
|
201
|
+
monkeypatch.setenv("LAYOUT_ENGINE", val)
|
|
202
|
+
assert dispatch.selected_engine() == "legacy"
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@pytest.mark.parametrize("val", ["elk", "ELK", " elk "])
|
|
206
|
+
def test_dispatch_selects_elk(monkeypatch, val):
|
|
207
|
+
monkeypatch.setenv("LAYOUT_ENGINE", val)
|
|
208
|
+
assert dispatch.selected_engine() == "elk"
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_dispatch_routes_to_elk_engine(monkeypatch):
|
|
212
|
+
monkeypatch.setenv("LAYOUT_ENGINE", "elk")
|
|
213
|
+
sentinel = {"positions": {"_": {"x": 1.0, "y": 2.0}}, "areas": {}, "bbox": {}}
|
|
214
|
+
called = {}
|
|
215
|
+
|
|
216
|
+
def fake(nodes, edges, opts=None, subset=None):
|
|
217
|
+
called["hit"] = True
|
|
218
|
+
return sentinel
|
|
219
|
+
monkeypatch.setattr(elk_engine, "layout", fake)
|
|
220
|
+
out = dispatch.layout([{"id": "n0"}], [])
|
|
221
|
+
assert called.get("hit") and out is sentinel
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""Environments: registry, default switching, credential binding, URL resolution.
|
|
2
|
+
|
|
3
|
+
The autouse _isolate_userdata fixture (conftest) pins the registry to a temp dir,
|
|
4
|
+
so every test starts from the built-in presets with the default = Internal-PROD.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from tools.procesio import config, environments as E
|
|
13
|
+
from tools.procesio.client import ProcesioClient
|
|
14
|
+
from tools.procesio.errors import UsageError
|
|
15
|
+
from tools.procesio.handlers import environment_admin as EA
|
|
16
|
+
from tools.procesio.tests.conftest import FakeResp, FakeSession
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# -- built-ins & defaults ---------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def test_builtin_presets_present():
|
|
22
|
+
names = set(E.all_environments())
|
|
23
|
+
assert {"Internal-PROD", "Internal-QA", "Internal-DEV"} <= names
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_default_is_prod_on_fresh_registry():
|
|
27
|
+
assert E.get_default() == "Internal-PROD"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_prod_urls_match_historical_defaults():
|
|
31
|
+
prod = E.get("Internal-PROD")
|
|
32
|
+
assert prod["web_base"] == config.DEFAULT_WEB_BASE
|
|
33
|
+
assert prod["app_base"] == config.DEFAULT_APP_BASE
|
|
34
|
+
assert prod["forms_base"] == config.DEFAULT_FORMS_BASE
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.parametrize("name,web,app,forms", [
|
|
38
|
+
("Internal-QA", "https://webapi-qa.procesio.app",
|
|
39
|
+
"https://qa.procesio.app", "https://forms-qa.procesio.app"),
|
|
40
|
+
("Internal-DEV", "https://webapi-dev.procesio.app",
|
|
41
|
+
"https://dev.procesio.app", "https://forms-dev.procesio.app"),
|
|
42
|
+
])
|
|
43
|
+
def test_qa_dev_urls(name, web, app, forms):
|
|
44
|
+
env = E.get(name)
|
|
45
|
+
assert env["web_base"] == web
|
|
46
|
+
assert env["app_base"] == app
|
|
47
|
+
assert env["forms_base"] == forms
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# -- resolution precedence --------------------------------------------------
|
|
51
|
+
|
|
52
|
+
def test_resolve_unbound_is_prod():
|
|
53
|
+
assert E.resolve(None, {"type": "apikey"})["name"] == "Internal-PROD"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_resolve_uses_credential_binding():
|
|
57
|
+
assert E.resolve(None, {"environment": "Internal-DEV"})["name"] == "Internal-DEV"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_explicit_name_beats_binding():
|
|
61
|
+
got = E.resolve("Internal-QA", {"environment": "Internal-DEV"})
|
|
62
|
+
assert got["name"] == "Internal-QA"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_default_pointer_beats_prod_fallback():
|
|
66
|
+
E.set_default("Internal-QA")
|
|
67
|
+
assert E.resolve(None, {"type": "apikey"})["name"] == "Internal-QA"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_case_insensitive_lookup():
|
|
71
|
+
assert E.canonical_name("internal-qa") == "Internal-QA"
|
|
72
|
+
assert E.resolve("INTERNAL-DEV", None)["name"] == "Internal-DEV"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_unknown_environment_raises():
|
|
76
|
+
with pytest.raises(UsageError):
|
|
77
|
+
E.get("Nope-PROD")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# -- add / set / remove -----------------------------------------------------
|
|
81
|
+
|
|
82
|
+
def test_add_client_environment_and_switch():
|
|
83
|
+
entry = E.add("Acme-PROD", web_base="https://webapi.acme.example",
|
|
84
|
+
app_base="https://acme.example",
|
|
85
|
+
forms_base="https://forms.acme.example")
|
|
86
|
+
assert entry["client"] == "Acme" and entry["env"] == "PROD"
|
|
87
|
+
assert entry["builtin"] is False
|
|
88
|
+
E.set_default("Acme-PROD")
|
|
89
|
+
assert E.get_default() == "Acme-PROD"
|
|
90
|
+
assert E.resolve(None, None)["web_base"] == "https://webapi.acme.example"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_add_trailing_slash_stripped():
|
|
94
|
+
entry = E.add("X-PROD", web_base="https://a/", app_base="https://b/",
|
|
95
|
+
forms_base="https://c/")
|
|
96
|
+
assert entry["web_base"] == "https://a"
|
|
97
|
+
assert entry["app_base"] == "https://b"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_add_requires_all_three_urls():
|
|
101
|
+
with pytest.raises(UsageError):
|
|
102
|
+
E.add("Y-PROD", web_base="https://a", app_base="", forms_base="https://c")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_add_rejects_bad_name():
|
|
106
|
+
with pytest.raises(UsageError):
|
|
107
|
+
E.add("has space", web_base="https://a", app_base="https://b",
|
|
108
|
+
forms_base="https://c")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_user_entry_overrides_builtin_url():
|
|
112
|
+
E.add("Internal-QA", web_base="https://moved-qa.example",
|
|
113
|
+
app_base="https://qa.moved.example",
|
|
114
|
+
forms_base="https://forms.moved.example")
|
|
115
|
+
assert E.get("Internal-QA")["web_base"] == "https://moved-qa.example"
|
|
116
|
+
# still flagged builtin (name is a built-in) but URL is the override
|
|
117
|
+
assert E.get("Internal-QA")["builtin"] is True
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_remove_builtin_blocked():
|
|
121
|
+
with pytest.raises(UsageError):
|
|
122
|
+
E.remove("Internal-DEV")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_remove_user_env_resets_default():
|
|
126
|
+
E.add("Z-PROD", web_base="https://a", app_base="https://b", forms_base="https://c",
|
|
127
|
+
make_default=True)
|
|
128
|
+
assert E.get_default() == "Z-PROD"
|
|
129
|
+
E.remove("Z-PROD")
|
|
130
|
+
assert E.get_default() == "Internal-PROD" # falls back
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_set_unknown_default_raises():
|
|
134
|
+
with pytest.raises(UsageError):
|
|
135
|
+
E.set_default("Ghost-PROD")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# -- handler surface --------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
def test_set_environment_handler_reports_credentials(store):
|
|
141
|
+
from tools.procesio import profiles
|
|
142
|
+
profiles.save_profile("qa-key", {"type": "apikey", "key": "N", "value": "V",
|
|
143
|
+
"environment": "Internal-QA"})
|
|
144
|
+
out = EA.set_environment(argparse.Namespace(name="Internal-QA"))
|
|
145
|
+
assert out["default_environment"] == "Internal-QA"
|
|
146
|
+
assert out["credentials"] == ["qa-key"]
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_list_environments_marks_default_and_creds(store):
|
|
150
|
+
from tools.procesio import profiles
|
|
151
|
+
profiles.save_profile("dev-key", {"type": "apikey", "key": "N", "value": "V",
|
|
152
|
+
"environment": "Internal-DEV"})
|
|
153
|
+
out = EA.list_environments(argparse.Namespace())
|
|
154
|
+
by_name = {e["name"]: e for e in out["environments"]}
|
|
155
|
+
assert by_name["Internal-PROD"]["is_default"] is True
|
|
156
|
+
assert by_name["Internal-DEV"]["credentials"] == ["dev-key"]
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# -- client URL injection ---------------------------------------------------
|
|
160
|
+
|
|
161
|
+
def _run(profile, session, environment=None):
|
|
162
|
+
c = ProcesioClient(profile=profile, name="t", session=session,
|
|
163
|
+
environment=environment)
|
|
164
|
+
c.get("/api/Workspaces")
|
|
165
|
+
return c, session.calls[0]
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_client_injects_bound_environment_url():
|
|
169
|
+
sess = FakeSession(queue=[FakeResp(200, {})])
|
|
170
|
+
_, call = _run({"type": "apikey", "key": "N", "value": "V",
|
|
171
|
+
"environment": "Internal-QA"}, sess)
|
|
172
|
+
assert call["url"] == "https://webapi-qa.procesio.app/api/Workspaces"
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_client_explicit_environment_overrides_binding():
|
|
176
|
+
sess = FakeSession(queue=[FakeResp(200, {})])
|
|
177
|
+
_, call = _run({"type": "apikey", "key": "N", "value": "V",
|
|
178
|
+
"environment": "Internal-QA"}, sess, environment="Internal-DEV")
|
|
179
|
+
assert call["url"] == "https://webapi-dev.procesio.app/api/Workspaces"
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_client_unbound_is_prod():
|
|
183
|
+
sess = FakeSession(queue=[FakeResp(200, {})])
|
|
184
|
+
_, call = _run({"type": "apikey", "key": "N", "value": "V"}, sess)
|
|
185
|
+
assert call["url"] == "https://webapi.procesio.app/api/Workspaces"
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def test_explicit_profile_url_override_beats_environment():
|
|
189
|
+
sess = FakeSession(queue=[FakeResp(200, {})])
|
|
190
|
+
_, call = _run({"type": "apikey", "key": "N", "value": "V",
|
|
191
|
+
"environment": "Internal-QA",
|
|
192
|
+
"web_base": "https://custom.example"}, sess)
|
|
193
|
+
assert call["url"] == "https://custom.example/api/Workspaces"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def test_client_does_not_mutate_caller_profile():
|
|
197
|
+
sess = FakeSession(queue=[FakeResp(200, {})])
|
|
198
|
+
original = {"type": "apikey", "key": "N", "value": "V",
|
|
199
|
+
"environment": "Internal-QA"}
|
|
200
|
+
ProcesioClient(profile=original, name="t", session=sess)
|
|
201
|
+
assert "web_base" not in original # injection copied, never mutated the input
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def test_userpass_login_origin_is_environment_app_host(store):
|
|
205
|
+
# `store` isolates the token cache to in-memory creds, so login actually runs.
|
|
206
|
+
login_resp = FakeResp(200, {"message": "ok"},
|
|
207
|
+
cookies={"__Host-procesio.access": "a.b.c"},
|
|
208
|
+
headers={"x-session-expires-at": "9999999999"})
|
|
209
|
+
sess = FakeSession(queue=[login_resp, FakeResp(200, {})])
|
|
210
|
+
_run({"type": "userpass", "username": "u", "password": "p",
|
|
211
|
+
"environment": "Internal-QA"}, sess)
|
|
212
|
+
login = sess.calls[0]
|
|
213
|
+
assert login["url"] == "https://webapi-qa.procesio.app/api/authentication"
|
|
214
|
+
assert login["headers"]["Origin"] == "https://qa.procesio.app"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Save-gate tests: FE (designer) + BE validation must block a process save unless
|
|
2
|
+
--force. Uses a fake client so no network is touched."""
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from tools.procesio.errors import ValidationBlocked
|
|
6
|
+
from tools.procesio.handlers import fevalidate
|
|
7
|
+
from tools.procesio.dto.process import builder as pb
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class _FakeClient:
|
|
11
|
+
"""Minimal client: serves an empty datatype catalog, an empty subprocess flow, and a
|
|
12
|
+
scripted /api/Projects/validate response."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, be_valid=True):
|
|
15
|
+
self.be_valid = be_valid
|
|
16
|
+
self.posts = []
|
|
17
|
+
|
|
18
|
+
def get(self, path, query=None):
|
|
19
|
+
if path.startswith("/api/DataTypes"):
|
|
20
|
+
return {"pageItems": []}
|
|
21
|
+
if path.startswith("/api/Projects/"):
|
|
22
|
+
return {"flow": {"variables": []}}
|
|
23
|
+
return {}
|
|
24
|
+
|
|
25
|
+
def post(self, path, body=None, query=None):
|
|
26
|
+
self.posts.append(path)
|
|
27
|
+
if path == "/api/Projects/validate":
|
|
28
|
+
return {"raw_text": ""} if self.be_valid else {"errors": ["bad runtime"]}
|
|
29
|
+
return {}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _valid_dto():
|
|
33
|
+
def act(aid, name, tmpl, ports):
|
|
34
|
+
return {"id": aid, "actionName": name, "actionTemplateName": tmpl,
|
|
35
|
+
"customData": {"type": "square", "name": name, "configuration": []},
|
|
36
|
+
"ports": ports}
|
|
37
|
+
return {"actions": [
|
|
38
|
+
act("start", "Start", "Start", [{"sourceId": "start", "destinationId": "mid"}]),
|
|
39
|
+
act("mid", "Mid", "Concatenate", [{"sourceId": "mid", "destinationId": "stop"}]),
|
|
40
|
+
act("stop", "Stop", "Stop", [])], "variables": []}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _broken_dto():
|
|
44
|
+
# no Stop, unconnected Start -> FE errors
|
|
45
|
+
dto = _valid_dto()
|
|
46
|
+
dto["actions"] = [dto["actions"][0]] # only Start, no ports target
|
|
47
|
+
dto["actions"][0]["ports"] = []
|
|
48
|
+
return dto
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_gate_passes_on_valid_flow():
|
|
52
|
+
rep = fevalidate.pre_save_validate(_FakeClient(be_valid=True), _valid_dto(), force=False)
|
|
53
|
+
assert rep["blocked"] is False
|
|
54
|
+
assert rep["fe"]["clean"] and rep["be"]["valid"]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_gate_blocks_on_fe_errors():
|
|
58
|
+
with pytest.raises(ValidationBlocked) as ei:
|
|
59
|
+
fevalidate.pre_save_validate(_FakeClient(be_valid=True), _broken_dto(), force=False)
|
|
60
|
+
assert ei.value.report["fe"]["error_count"] > 0
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_gate_blocks_on_be_invalid():
|
|
64
|
+
with pytest.raises(ValidationBlocked):
|
|
65
|
+
fevalidate.pre_save_validate(_FakeClient(be_valid=False), _valid_dto(), force=False)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_force_bypasses_block():
|
|
69
|
+
rep = fevalidate.pre_save_validate(_FakeClient(be_valid=False), _broken_dto(), force=True)
|
|
70
|
+
assert rep["blocked"] is True and rep["forced"] is True # reported, not raised
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_process_component_has_save_gate_wired():
|
|
74
|
+
# the wiring the create/edit paths depend on
|
|
75
|
+
assert pb.COMPONENT.save_gate is not None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_edit_runs_gate_and_blocks(monkeypatch):
|
|
79
|
+
# _edit builds the DTO then gates before PUT; a broken build must never reach PUT
|
|
80
|
+
calls = {"put": 0}
|
|
81
|
+
fake = _FakeClient(be_valid=True)
|
|
82
|
+
|
|
83
|
+
def fake_build(config, ctx):
|
|
84
|
+
return _broken_dto()
|
|
85
|
+
|
|
86
|
+
monkeypatch.setattr(pb, "build", fake_build)
|
|
87
|
+
fake.put = lambda *a, **k: calls.__setitem__("put", calls["put"] + 1) # noqa: E731
|
|
88
|
+
with pytest.raises(ValidationBlocked):
|
|
89
|
+
pb._edit(fake, "some-id", {"title": "t", "actions": []}, {"_force": False})
|
|
90
|
+
assert calls["put"] == 0 # gate aborted before the PUT
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_flowlint_extras_folded_into_gate():
|
|
94
|
+
# flow-lint's unique designer save-blockers (here: Node code binding an error-scope
|
|
95
|
+
# variable) are merged into run_fe_validation as blocking errors.
|
|
96
|
+
from tools.procesio.handlers.flowlint import CODE_PID
|
|
97
|
+
flow = {"actions": [{
|
|
98
|
+
"actionName": "Compose", "actionTemplateName": "Node",
|
|
99
|
+
"customData": {"name": "Compose", "type": "square", "configuration": []},
|
|
100
|
+
"parameters": [{"tabPropertyId": CODE_PID, "value": "x",
|
|
101
|
+
"variable": [{"id": 0, "variableId": "e1"}]}]}],
|
|
102
|
+
"variables": [{"id": "e1", "name": "err_x", "type": 20, "isError": True}]}
|
|
103
|
+
rep = fevalidate.run_fe_validation(_FakeClient(be_valid=True), flow, include_types=False)
|
|
104
|
+
assert any(e["code"] == "CODE_ERROR_SCOPE" for e in rep["errors"])
|