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,41 @@
|
|
|
1
|
+
"""put-projects: empty-body echo hardening (O4) — warns that an empty success can lie."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from tools.procesio import main
|
|
5
|
+
from tools.procesio.client import ProcesioClient
|
|
6
|
+
from tools.procesio.tests.conftest import FakeResp, FakeSession
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _builder(session):
|
|
10
|
+
return lambda prof: ProcesioClient(
|
|
11
|
+
profile={"type": "apikey", "key": "N", "value": "V"}, name="t", session=session)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_empty_body_put_warns_and_reports_meta():
|
|
15
|
+
# 200 with an empty body -> _parse_body yields {"raw_text": ""} (the O4 shape).
|
|
16
|
+
sess = FakeSession(queue=[FakeResp(200, None, text="")])
|
|
17
|
+
out = main.dispatch("put-projects", ["--body", '{"id": "X", "name": "n"}'],
|
|
18
|
+
client_builder=_builder(sess))
|
|
19
|
+
assert "warning" in out
|
|
20
|
+
assert "empty" in out["warning"].lower() and "verify" in out["warning"].lower()
|
|
21
|
+
assert out["http"]["status"] == 200
|
|
22
|
+
assert out["http"]["body_len"] == 0
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_non_empty_body_put_has_no_warning():
|
|
26
|
+
body_text = '{"id": "X"}'
|
|
27
|
+
sess = FakeSession(queue=[FakeResp(200, {"id": "X"}, text=body_text)])
|
|
28
|
+
out = main.dispatch("put-projects", ["--body", '{"id": "X"}'],
|
|
29
|
+
client_builder=_builder(sess))
|
|
30
|
+
assert "warning" not in out
|
|
31
|
+
assert out["http"]["status"] == 200
|
|
32
|
+
assert out["http"]["body_len"] == len(body_text)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_put_projects_dry_run_composes_without_sending():
|
|
36
|
+
sess = FakeSession()
|
|
37
|
+
out = main.dispatch("put-projects", ["--body", '{"id": "X"}', "--dry-run"],
|
|
38
|
+
client_builder=_builder(sess))
|
|
39
|
+
assert out["dry_run"] is True
|
|
40
|
+
assert out["method"] == "PUT" and out["path"] == "/api/Projects"
|
|
41
|
+
assert sess.calls == []
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Unit tests for the request-reliability primitives (offline, no HTTP)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import random
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from tools.procesio import reliability
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# -- deadline resolution ----------------------------------------------------
|
|
13
|
+
|
|
14
|
+
def test_resolve_deadline_class_defaults():
|
|
15
|
+
assert reliability.resolve_deadline("GET", reliability.DEFAULT) == reliability.READ_DEADLINE
|
|
16
|
+
assert reliability.resolve_deadline("PUT", reliability.DEFAULT) == reliability.WRITE_DEADLINE
|
|
17
|
+
assert reliability.resolve_deadline("POST", reliability.DEFAULT) == reliability.WRITE_DEADLINE
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_resolve_deadline_none_is_exempt():
|
|
21
|
+
assert reliability.resolve_deadline("GET", None) is None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_resolve_deadline_numeric_override():
|
|
25
|
+
assert reliability.resolve_deadline("GET", 5) == 5.0
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_resolve_deadline_env_optout(monkeypatch):
|
|
29
|
+
monkeypatch.setenv(reliability.ENV_NO_DEADLINE, "1")
|
|
30
|
+
assert reliability.resolve_deadline("GET", reliability.DEFAULT) is None
|
|
31
|
+
assert reliability.resolve_deadline("PUT", 30) is None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# -- retry policy -----------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
def test_is_retryable_get_only_transient():
|
|
37
|
+
assert reliability.is_retryable("GET", 503, 0) is True
|
|
38
|
+
assert reliability.is_retryable("GET", 429, 0) is True
|
|
39
|
+
# 500 is deliberately excluded (may be deterministic, not transient)
|
|
40
|
+
assert reliability.is_retryable("GET", 500, 0) is False
|
|
41
|
+
# writes are NEVER retryable — the single structural guarantee
|
|
42
|
+
assert reliability.is_retryable("POST", 503, 0) is False
|
|
43
|
+
assert reliability.is_retryable("PUT", 503, 0) is False
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_is_retryable_respects_attempt_budget():
|
|
47
|
+
assert reliability.is_retryable("GET", 503, reliability.MAX_RETRIES) is False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_retry_env_optout(monkeypatch):
|
|
51
|
+
monkeypatch.setenv(reliability.ENV_NO_RETRY, "true")
|
|
52
|
+
assert reliability.is_retryable("GET", 503, 0) is False
|
|
53
|
+
assert reliability.network_error_retryable("GET", 0) is False
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_network_error_retryable_get_only():
|
|
57
|
+
assert reliability.network_error_retryable("GET", 0) is True
|
|
58
|
+
assert reliability.network_error_retryable("POST", 0) is False
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_full_jitter_within_bounds():
|
|
62
|
+
rng = random.Random(1234)
|
|
63
|
+
for attempt in range(1, 12):
|
|
64
|
+
ceiling = min(reliability.BACKOFF_CAP, reliability.BACKOFF_BASE * (2 ** attempt))
|
|
65
|
+
v = reliability.full_jitter(attempt, rng)
|
|
66
|
+
assert 0.0 <= v <= ceiling
|
|
67
|
+
# large attempt is capped
|
|
68
|
+
assert reliability.full_jitter(20, rng) <= reliability.BACKOFF_CAP
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_parse_retry_after():
|
|
72
|
+
assert reliability.parse_retry_after({"Retry-After": "3"}) == 3.0
|
|
73
|
+
assert reliability.parse_retry_after({"retry-after": "2"}) == 2.0 # case-insensitive
|
|
74
|
+
assert reliability.parse_retry_after({"Retry-After": "999"}) == reliability.BACKOFF_CAP
|
|
75
|
+
assert reliability.parse_retry_after({"Retry-After": "Wed, 21 Oct"}) is None # HTTP-date ignored
|
|
76
|
+
assert reliability.parse_retry_after({}) is None
|
|
77
|
+
assert reliability.parse_retry_after(None) is None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# -- total deadline ---------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
def test_run_with_deadline_returns_value():
|
|
83
|
+
assert reliability.run_with_deadline(lambda: 42, 1.0) == 42
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_run_with_deadline_no_deadline_runs_inline():
|
|
87
|
+
assert reliability.run_with_deadline(lambda: "ok", None) == "ok"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_run_with_deadline_trips_on_slow_fn():
|
|
91
|
+
def slow():
|
|
92
|
+
time.sleep(1.0)
|
|
93
|
+
return "late"
|
|
94
|
+
with pytest.raises(reliability.DeadlineHit):
|
|
95
|
+
reliability.run_with_deadline(slow, 0.1)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_run_with_deadline_reraises_worker_exception():
|
|
99
|
+
def boom():
|
|
100
|
+
raise ValueError("kaboom")
|
|
101
|
+
with pytest.raises(ValueError, match="kaboom"):
|
|
102
|
+
reliability.run_with_deadline(boom, 1.0)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_run_with_deadline_zero_timeout_trips_immediately():
|
|
106
|
+
with pytest.raises(reliability.DeadlineHit):
|
|
107
|
+
reliability.run_with_deadline(lambda: 1, 0)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""The removal gate: a desired-state save may not silently delete what it omits.
|
|
2
|
+
|
|
3
|
+
Why this exists. `process-edit --config` replaces the definition, so anything the config
|
|
4
|
+
leaves out is removed, and the payload cannot say whether that was meant: a config with 4
|
|
5
|
+
actions against a live flow of 13 looks identical whether the author intended to drop 9 or
|
|
6
|
+
had lost track of the flow. Neither existing guard catches it — the validation gate asks
|
|
7
|
+
whether the RESULT is valid (a truncated flow usually still is), and `PUT /api/Projects`
|
|
8
|
+
persists even when it answers HTTP 400 (by design: unfinished work must be saveable).
|
|
9
|
+
|
|
10
|
+
Seen live: an incomplete write cut a 13-action flow to 2, and the next step — reading that
|
|
11
|
+
state and rebuilding from a partial picture — dropped 8 more variables. So the gate does not
|
|
12
|
+
judge the removal; it makes the consequence visible before it is paid and asks for intent.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
from tools.procesio.dto.process.builder import _removal_gate
|
|
19
|
+
from tools.procesio.errors import RemovalBlocked
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _live(actions=(), variables=()):
|
|
23
|
+
return {"_live_flow": {
|
|
24
|
+
"actions": [{"name": n} for n in actions],
|
|
25
|
+
"variables": [{"name": n} for n in variables],
|
|
26
|
+
}}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _dto(actions=(), variables=()):
|
|
30
|
+
return {"Actions": [{"Name": n} for n in actions],
|
|
31
|
+
"Variables": [{"Name": n} for n in variables]}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_keeping_everything_passes():
|
|
35
|
+
_removal_gate(_dto(["Start", "Trim", "Stop"], ["a", "b"]),
|
|
36
|
+
_live(["Start", "Trim", "Stop"], ["a", "b"]))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_adding_is_never_a_removal():
|
|
40
|
+
_removal_gate(_dto(["Start", "Trim", "To Upper", "Stop"], ["a", "b", "c"]),
|
|
41
|
+
_live(["Start", "Trim", "Stop"], ["a", "b"]))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_dropping_an_action_is_refused():
|
|
45
|
+
with pytest.raises(RemovalBlocked) as e:
|
|
46
|
+
_removal_gate(_dto(["Start", "Stop"]), _live(["Start", "Trim", "Stop"]))
|
|
47
|
+
assert e.value.removed["actions"] == ["Trim"]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_dropping_a_variable_is_refused():
|
|
51
|
+
with pytest.raises(RemovalBlocked) as e:
|
|
52
|
+
_removal_gate(_dto(["Start"], ["a"]), _live(["Start"], ["a", "b"]))
|
|
53
|
+
assert e.value.removed["variables"] == ["b"]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_the_message_names_what_would_disappear():
|
|
57
|
+
"""The gate does not decide whether the removal is right - the caller does, from this
|
|
58
|
+
list. One line means an intentional edit; nine mean a lost picture of the flow."""
|
|
59
|
+
with pytest.raises(RemovalBlocked) as e:
|
|
60
|
+
_removal_gate(_dto(["Start", "Stop"], ["payload"]),
|
|
61
|
+
_live(["Start", "Trim", "Normalize Diacritics", "Stop"],
|
|
62
|
+
["payload", "customerObj", "emailObj"]))
|
|
63
|
+
msg = str(e.value)
|
|
64
|
+
assert "2 action(s): Trim, Normalize Diacritics" in msg
|
|
65
|
+
assert "2 variable(s): customerObj, emailObj" in msg
|
|
66
|
+
assert "--allow-remove" in msg
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_allow_remove_lets_it_through():
|
|
70
|
+
ctx = _live(["Start", "Trim", "Stop"], ["a", "b"])
|
|
71
|
+
ctx["_allow_remove"] = True
|
|
72
|
+
_removal_gate(_dto(["Start"]), ctx)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_generated_error_ports_are_not_authored_state():
|
|
76
|
+
"""Error variables come and go with their owning action, so their absence from a
|
|
77
|
+
config is never the caller's removal."""
|
|
78
|
+
ctx = {"_live_flow": {"actions": [{"name": "Start"}], "variables": [
|
|
79
|
+
{"name": "a"}, {"name": "Trim_error", "isError": True}]}}
|
|
80
|
+
_removal_gate(_dto(["Start"], ["a"]), ctx)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_pascal_and_camel_live_shapes_both_read():
|
|
84
|
+
"""The live flow comes back camelCase from the API and PascalCase from a DTO round
|
|
85
|
+
trip; the gate must not go blind on either."""
|
|
86
|
+
ctx = {"_live_flow": {"Actions": [{"Name": "Start"}, {"Name": "Trim"}],
|
|
87
|
+
"Variables": [{"Name": "a"}]}}
|
|
88
|
+
with pytest.raises(RemovalBlocked):
|
|
89
|
+
_removal_gate(_dto(["Start"], ["a"]), ctx)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_no_live_flow_is_not_a_removal():
|
|
93
|
+
"""A create, or an edit whose live read failed, has nothing to compare against - the
|
|
94
|
+
gate must stay out of the way rather than block on missing evidence."""
|
|
95
|
+
_removal_gate(_dto(["Start", "Stop"]), {})
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""CRUD-parity + oracle actions: correct endpoint/method, bodies, multipart import."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
from tools.procesio import main
|
|
7
|
+
from tools.procesio.client import ProcesioClient
|
|
8
|
+
from tools.procesio.tests.conftest import FakeResp, FakeSession
|
|
9
|
+
|
|
10
|
+
APIKEY = {"type": "apikey", "key": "N", "value": "V"}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _builder(session):
|
|
14
|
+
return lambda prof: ProcesioClient(profile=APIKEY, name="t", session=session)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _call(action, argv, session):
|
|
18
|
+
return main.dispatch(action, argv, client_builder=_builder(session))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_get_delete_list_endpoints():
|
|
22
|
+
# get
|
|
23
|
+
s = FakeSession(queue=[FakeResp(200, {"id": "F1"})])
|
|
24
|
+
out = _call("form-get", ["--id", "F1"], s)
|
|
25
|
+
assert s.calls[0]["method"] == "GET" and s.calls[0]["url"].endswith("/api/FormTemplate/F1")
|
|
26
|
+
assert out == {"result": {"id": "F1"}}
|
|
27
|
+
# delete
|
|
28
|
+
s = FakeSession(queue=[FakeResp(200, {})])
|
|
29
|
+
out = _call("process-delete", ["--id", "P1"], s)
|
|
30
|
+
assert s.calls[0]["method"] == "DELETE" and s.calls[0]["url"].endswith("/api/Projects/P1")
|
|
31
|
+
assert out == {"deleted": True, "id": "P1"}
|
|
32
|
+
# list (pageItems normalized)
|
|
33
|
+
s = FakeSession(queue=[FakeResp(200, {"pageItems": [{"id": "a"}, {"id": "b"}]})])
|
|
34
|
+
out = _call("document-list", [], s)
|
|
35
|
+
assert s.calls[0]["url"].endswith("/api/DocumentTemplate")
|
|
36
|
+
assert out == {"count": 2, "items": [{"id": "a"}, {"id": "b"}]}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_toggle_activation_sends_the_state_header():
|
|
40
|
+
"""The target state travels in a `state` header, not the body or the path.
|
|
41
|
+
|
|
42
|
+
Without it the endpoint deactivates every time while answering success, which is
|
|
43
|
+
what made it look, for a while, like an endpoint that could only turn things off.
|
|
44
|
+
"""
|
|
45
|
+
s = FakeSession(queue=[
|
|
46
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": False}]}), # before
|
|
47
|
+
FakeResp(200, {"value": None, "errors": []}), # the PATCH
|
|
48
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": True}]}), # after
|
|
49
|
+
])
|
|
50
|
+
out = _call("process-toggle-activation", ["--id", "P1", "--state", "true"], s)
|
|
51
|
+
patch = s.calls[1]
|
|
52
|
+
assert patch["method"] == "PATCH"
|
|
53
|
+
assert patch["url"].endswith("/api/Projects/P1/toggle-activation")
|
|
54
|
+
hdrs = {k.lower(): v for k, v in (patch.get("headers") or {}).items()}
|
|
55
|
+
assert hdrs.get("state") == "true", "the target state must be sent as the `state` header"
|
|
56
|
+
assert out["requested"] is True and out["active"] is True and out["changed"] is True
|
|
57
|
+
assert "warning" not in out
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_toggle_activation_deactivates_with_state_false():
|
|
61
|
+
s = FakeSession(queue=[
|
|
62
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": True}]}),
|
|
63
|
+
FakeResp(200, {"value": None, "errors": []}),
|
|
64
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": False}]}),
|
|
65
|
+
])
|
|
66
|
+
out = _call("process-toggle-activation", ["--id", "P1", "--state", "false"], s)
|
|
67
|
+
hdrs = {k.lower(): v for k, v in (s.calls[1].get("headers") or {}).items()}
|
|
68
|
+
assert hdrs.get("state") == "false"
|
|
69
|
+
assert out["requested"] is False and out["active"] is False and out["changed"] is True
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_toggle_activation_warns_when_the_result_is_not_what_was_asked():
|
|
73
|
+
"""The response is identical in every case, so only the read-back can disagree."""
|
|
74
|
+
s = FakeSession(queue=[
|
|
75
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": False}]}),
|
|
76
|
+
FakeResp(200, {"value": None, "errors": []}),
|
|
77
|
+
FakeResp(200, {"pageItems": [{"id": "P1", "active": False}]}), # asked true, still false
|
|
78
|
+
])
|
|
79
|
+
out = _call("process-toggle-activation", ["--id", "P1", "--state", "true"], s)
|
|
80
|
+
assert out["requested"] is True and out["active"] is False
|
|
81
|
+
assert out["changed"] is False
|
|
82
|
+
assert "asked for active=True" in out["warning"]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_toggle_activation_warns_when_it_cannot_confirm():
|
|
86
|
+
s = FakeSession(queue=[
|
|
87
|
+
FakeResp(200, {"pageItems": [{"id": "OTHER", "active": True}]}), # P1 not present
|
|
88
|
+
FakeResp(200, {"value": None, "errors": []}),
|
|
89
|
+
FakeResp(200, {"pageItems": [{"id": "OTHER", "active": True}]}),
|
|
90
|
+
])
|
|
91
|
+
out = _call("process-toggle-activation", ["--id", "P1", "--state", "true"], s)
|
|
92
|
+
assert out["active"] is None and "warning" in out
|
|
93
|
+
assert out["changed"] is None, "unknown must not read as 'did not change'"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_form_duplicate():
|
|
97
|
+
s = FakeSession(queue=[FakeResp(200, {"id": "new"})])
|
|
98
|
+
out = _call("form-duplicate", ["--id", "F1"], s)
|
|
99
|
+
assert s.calls[0]["method"] == "POST" and s.calls[0]["url"].endswith("/api/FormTemplate/F1/duplicate")
|
|
100
|
+
assert out["duplicated"] is True
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_process_validate_empty_response_is_valid():
|
|
104
|
+
# GET the flow, then POST validate -> empty 200 body == valid
|
|
105
|
+
s = FakeSession(queue=[
|
|
106
|
+
FakeResp(200, {"flow": {"id": "P1", "title": "T"}}),
|
|
107
|
+
FakeResp(200, text="")])
|
|
108
|
+
out = _call("process-validate", ["--id", "P1"], s)
|
|
109
|
+
assert s.calls[0]["method"] == "GET" and s.calls[0]["url"].endswith("/api/Projects/P1")
|
|
110
|
+
assert s.calls[1]["method"] == "POST" and s.calls[1]["url"].endswith("/api/Projects/validate")
|
|
111
|
+
assert s.calls[1]["json"]["title"] == "T" # posts the flow DTO
|
|
112
|
+
assert out["isValid"] is True and out["errors"] == []
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_process_validate_errors_surface():
|
|
116
|
+
# validator rejects -> platform 4xx with the error list -> isValid False + errors
|
|
117
|
+
s = FakeSession(queue=[
|
|
118
|
+
FakeResp(200, {"flow": {"id": "P1"}}),
|
|
119
|
+
FakeResp(400, {"body": [{"value": "Action has too many input ports."}]})])
|
|
120
|
+
out = _call("process-validate", ["--id", "P1"], s)
|
|
121
|
+
assert out["isValid"] is False
|
|
122
|
+
assert out["errors"] == [{"value": "Action has too many input ports."}]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_webhook_launch_with_payload():
|
|
126
|
+
s = FakeSession(queue=[FakeResp(200, {"ok": True})])
|
|
127
|
+
out = _call("webhook-launch", ["--id", "W1", "--payload", '{"x":1}'], s)
|
|
128
|
+
assert s.calls[0]["method"] == "POST" and s.calls[0]["url"].endswith("/api/Webhooks/launch/W1")
|
|
129
|
+
assert s.calls[0]["json"] == {"x": 1} and out["launched"] is True
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def test_import_multipart(tmp_path):
|
|
133
|
+
bundle = tmp_path / "b.procesio"
|
|
134
|
+
bundle.write_bytes(b'{"Flows":[]}')
|
|
135
|
+
s = FakeSession(queue=[FakeResp(200, {"imported": 1})])
|
|
136
|
+
out = _call("import", ["--file", str(bundle)], s)
|
|
137
|
+
assert s.calls[0]["method"] == "POST" and s.calls[0]["url"].endswith("/api/Transport/import")
|
|
138
|
+
# ⚠ THE PART IS `importedData`, NOT `file`. This assertion previously
|
|
139
|
+
# encoded the wrong name: `POST api/Transport/import` documents the part as
|
|
140
|
+
# `importedData`, and the endpoint reports a wrongly named part only as a
|
|
141
|
+
# generic 403/MIGRATE, so nothing about the response would have revealed it.
|
|
142
|
+
field = s.calls[0]["files"]["importedData"]
|
|
143
|
+
assert field[0] == "b.procesio" and field[1] == b'{"Flows":[]}'
|
|
144
|
+
# ⚠ and all seven required boolean headers must go with it
|
|
145
|
+
sent = s.calls[0].get("headers") or {}
|
|
146
|
+
for wire in ("overrideData", "importDataTypes", "importFlows",
|
|
147
|
+
"importCredentials", "importDocuments", "importForms",
|
|
148
|
+
"importDataStores"):
|
|
149
|
+
assert sent.get(wire) == "true", "missing required header " + wire
|
|
150
|
+
assert out["imported"] is True and out["bytes"] == 12
|
|
151
|
+
# the captured headers also carry auth and user-agent, so the echo is
|
|
152
|
+
# compared as a SUBSET rather than for equality
|
|
153
|
+
assert out["headers_sent"].items() <= sent.items(), (
|
|
154
|
+
"the result must echo the flags it sent: a 403 from this endpoint "
|
|
155
|
+
"cannot be read without knowing what was asked")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_credential_test_builds_dto_and_probes():
|
|
159
|
+
# GET /api/Credentials/types (template resolve), POST /api/Credentials/test (probe x2:
|
|
160
|
+
# once inside prepare_ctx, once in the action) -> return the last verdict
|
|
161
|
+
tmpl = {"name": "REST API", "gid": "G", "pid": "P",
|
|
162
|
+
"properties": [{"id": "u", "label": "URL", "validations": {"isRequired": True}}]}
|
|
163
|
+
def responder(method, url, kw):
|
|
164
|
+
if url.endswith("/api/Credentials/types"):
|
|
165
|
+
return FakeResp(200, [tmpl])
|
|
166
|
+
if url.endswith("/api/Credentials/test"):
|
|
167
|
+
return FakeResp(200, {"isSuccess": True})
|
|
168
|
+
return FakeResp(200, {})
|
|
169
|
+
s = FakeSession(responder=responder)
|
|
170
|
+
out = _call("credential-test", ["--config", json.dumps({"template": "REST API", "name": "x",
|
|
171
|
+
"properties": {"URL": "https://a"}})], s)
|
|
172
|
+
assert any(c["url"].endswith("/api/Credentials/test") for c in s.calls)
|
|
173
|
+
assert out == {"tested": True, "isSuccess": True, "result": {"isSuccess": True}}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""The validity mark a save leaves behind, and the value a save reports.
|
|
2
|
+
|
|
3
|
+
These pin behaviour measured against the live platform, not a reading of the docs:
|
|
4
|
+
|
|
5
|
+
* PROCESIO never computes `isValid`. It stores whatever the PUT body carries, and
|
|
6
|
+
defaults it to TRUE when the body omits the field.
|
|
7
|
+
* So a writer that passes a fetched flow straight through leaves a corrected process
|
|
8
|
+
marked broken for ever, and a writer that reports its own pre-save validation
|
|
9
|
+
describes the flow it sent rather than the one the platform kept.
|
|
10
|
+
|
|
11
|
+
Both were real: `node-set-param` on a correct process marked invalid reported
|
|
12
|
+
`isValid: true, put: true` while the server went on holding `isValid: false`.
|
|
13
|
+
|
|
14
|
+
A fake client throughout - no network.
|
|
15
|
+
"""
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
from tools.procesio.handlers import fevalidate
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class _Server:
|
|
22
|
+
"""A PROCESIO that stores `isValid` verbatim and never recomputes it - which is
|
|
23
|
+
exactly what the live one was measured doing."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, stored_valid=False, fe_clean=True, be_valid=True):
|
|
26
|
+
self.stored = {"id": "p1", "isValid": stored_valid, "variables": [], "actions": []}
|
|
27
|
+
self.fe_clean = fe_clean
|
|
28
|
+
self.be_valid = be_valid
|
|
29
|
+
self.puts = []
|
|
30
|
+
|
|
31
|
+
def get(self, path, query=None):
|
|
32
|
+
if path.startswith("/api/DataTypes"):
|
|
33
|
+
return {"pageItems": []}
|
|
34
|
+
if path.startswith("/api/Projects/"):
|
|
35
|
+
return {"flow": dict(self.stored)}
|
|
36
|
+
return {}
|
|
37
|
+
|
|
38
|
+
def post(self, path, body=None, query=None):
|
|
39
|
+
if path == "/api/Projects/validate":
|
|
40
|
+
return {"raw_text": ""} if self.be_valid else {"errors": ["bad runtime"]}
|
|
41
|
+
return {}
|
|
42
|
+
|
|
43
|
+
def put(self, path, body=None, query=None):
|
|
44
|
+
self.puts.append(body)
|
|
45
|
+
self.stored["isValid"] = body.get("isValid") # verbatim, like the real one
|
|
46
|
+
return {"raw_text": ""}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_a_clean_save_clears_a_stale_invalid_mark():
|
|
50
|
+
"""The reported symptom: fix the process, save it, and it stays marked broken."""
|
|
51
|
+
srv = _Server(stored_valid=False)
|
|
52
|
+
flow = {"id": "p1", "isValid": False}
|
|
53
|
+
out = fevalidate.save_flow(srv, flow, flow_id="p1", valid=True)
|
|
54
|
+
assert srv.stored["isValid"] is True, "the save must clear the stale mark"
|
|
55
|
+
assert out["isValid"] is True, "and must report what the server now holds"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_the_reported_value_is_re_read_not_the_value_we_sent():
|
|
59
|
+
"""A server that disagrees with the body must be believed over our own measurement."""
|
|
60
|
+
srv = _Server(stored_valid=False)
|
|
61
|
+
|
|
62
|
+
def stubborn_put(path, body=None, query=None):
|
|
63
|
+
srv.puts.append(body) # accepts the write, keeps its own answer
|
|
64
|
+
return {"raw_text": ""}
|
|
65
|
+
srv.put = stubborn_put
|
|
66
|
+
|
|
67
|
+
out = fevalidate.save_flow(srv, {"id": "p1"}, flow_id="p1", valid=True)
|
|
68
|
+
assert out["stamped"] is True, "we asked for valid"
|
|
69
|
+
assert out["isValid"] is False, "but the server kept false, and that is what is reported"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_an_invalid_flow_is_stamped_invalid_rather_than_left_alone():
|
|
73
|
+
"""Saving a half-built process is intended; marking it valid is not."""
|
|
74
|
+
srv = _Server(stored_valid=True)
|
|
75
|
+
out = fevalidate.save_flow(srv, {"id": "p1", "isValid": True}, flow_id="p1", valid=False)
|
|
76
|
+
assert srv.stored["isValid"] is False
|
|
77
|
+
assert out["isValid"] is False
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_the_field_is_never_omitted():
|
|
81
|
+
"""Omitting it makes the platform default to true, which marks broken work valid."""
|
|
82
|
+
srv = _Server()
|
|
83
|
+
fevalidate.save_flow(srv, {"id": "p1"}, flow_id="p1", valid=False)
|
|
84
|
+
assert "isValid" in srv.puts[0], "the body must carry the mark explicitly"
|
|
85
|
+
assert srv.puts[0]["isValid"] is False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_a_failed_read_back_does_not_fail_a_save_that_landed():
|
|
89
|
+
srv = _Server()
|
|
90
|
+
|
|
91
|
+
def blind_get(path, query=None):
|
|
92
|
+
if path.startswith("/api/Projects/"):
|
|
93
|
+
raise RuntimeError("read-back unavailable")
|
|
94
|
+
return {"pageItems": []}
|
|
95
|
+
srv.get = blind_get
|
|
96
|
+
|
|
97
|
+
out = fevalidate.save_flow(srv, {"id": "p1"}, flow_id="p1", valid=True)
|
|
98
|
+
assert srv.puts, "the PUT still happened"
|
|
99
|
+
assert out["isValid"] is None
|
|
100
|
+
assert "readback_error" in out
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_every_surgical_writer_goes_through_the_stamping_save():
|
|
104
|
+
"""No handler may PUT a fetched flow directly: that is how the mark went stale."""
|
|
105
|
+
import pathlib
|
|
106
|
+
root = pathlib.Path(fevalidate.__file__).resolve().parent
|
|
107
|
+
for name in ("nodeparams.py", "sqlactions.py"):
|
|
108
|
+
src = (root / name).read_text(encoding="utf-8")
|
|
109
|
+
assert 'client.put("/api/Projects", flow)' not in src, (
|
|
110
|
+
f"{name} PUTs a fetched flow directly; use fevalidate.save_flow so the "
|
|
111
|
+
"validity mark is stamped and the stored value re-read")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_a_forced_save_does_not_file_a_broken_process_as_valid():
|
|
115
|
+
"""build() hardcodes IsValid=True; the gate must overwrite it with the verdict.
|
|
116
|
+
|
|
117
|
+
Without this, `process-edit --force` - the supported way to save half-finished work -
|
|
118
|
+
marked every broken process valid, and the designer's own error list disagreed with
|
|
119
|
+
the flag stored beside it.
|
|
120
|
+
"""
|
|
121
|
+
from tools.procesio.dto.process import builder as pb
|
|
122
|
+
|
|
123
|
+
class _C:
|
|
124
|
+
def get(self, path, query=None):
|
|
125
|
+
return {"pageItems": []} if path.startswith("/api/DataTypes") else {"flow": {"variables": []}}
|
|
126
|
+
|
|
127
|
+
def post(self, path, body=None, query=None):
|
|
128
|
+
return {"raw_text": ""} # BE says valid; the designer will not
|
|
129
|
+
|
|
130
|
+
dto = {"IsValid": True, "Actions": [], "Variables": []}
|
|
131
|
+
pb._save_gate(_C(), dto, {"_force": True})
|
|
132
|
+
assert dto["IsValid"] is False, "a flow with no Start/Stop is not valid, forced or not"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def test_a_clean_save_still_stamps_valid():
|
|
136
|
+
from tools.procesio.dto.process import builder as pb
|
|
137
|
+
|
|
138
|
+
class _C:
|
|
139
|
+
def get(self, path, query=None):
|
|
140
|
+
return {"pageItems": []} if path.startswith("/api/DataTypes") else {"flow": {"variables": []}}
|
|
141
|
+
|
|
142
|
+
def post(self, path, body=None, query=None):
|
|
143
|
+
return {"raw_text": ""}
|
|
144
|
+
|
|
145
|
+
def act(aid, name, tmpl, ports):
|
|
146
|
+
return {"id": aid, "actionName": name, "actionTemplateName": tmpl,
|
|
147
|
+
"customData": {"type": "square", "name": name, "configuration": []},
|
|
148
|
+
"ports": ports}
|
|
149
|
+
|
|
150
|
+
dto = {"IsValid": True, "Variables": [], "actions": [
|
|
151
|
+
act("start", "Start", "Start", [{"sourceId": "start", "destinationId": "stop"}]),
|
|
152
|
+
act("stop", "Stop", "Stop", [])]}
|
|
153
|
+
pb._save_gate(_C(), dto, {})
|
|
154
|
+
assert dto["IsValid"] is True
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_no_process_writer_anywhere_puts_a_flow_without_stamping_it():
|
|
158
|
+
"""The rule is repo-wide, not per-handler: every save decides the mark.
|
|
159
|
+
|
|
160
|
+
A rename or a re-layout is a save like any other, and leaving those two as
|
|
161
|
+
pass-throughs meant the fixed bug could walk back in through the least
|
|
162
|
+
suspicious door - renaming a node should not be able to file a repaired
|
|
163
|
+
process as broken.
|
|
164
|
+
|
|
165
|
+
process_layout and process_naming are included deliberately. dto/process/builder
|
|
166
|
+
is not: it stamps in its own save gate, which covers create and edit together.
|
|
167
|
+
"""
|
|
168
|
+
import pathlib
|
|
169
|
+
root = pathlib.Path(fevalidate.__file__).resolve().parent
|
|
170
|
+
for name in ("nodeparams.py", "sqlactions.py", "process_layout.py", "process_naming.py"):
|
|
171
|
+
src = (root / name).read_text(encoding="utf-8")
|
|
172
|
+
for bad in ('client.put("/api/Projects", flow)',
|
|
173
|
+
'client.put("/api/Projects", new_flow)'):
|
|
174
|
+
assert bad not in src, (
|
|
175
|
+
f"{name} PUTs a fetched flow directly; route it through "
|
|
176
|
+
"fevalidate.save_flow so the mark is stamped and re-read")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_save_arranges_the_canvas_by_default(monkeypatch):
|
|
180
|
+
from tools.procesio.handlers import fevalidate
|
|
181
|
+
monkeypatch.delenv("PROCESIO_KEEP_LAYOUT", raising=False)
|
|
182
|
+
called = {}
|
|
183
|
+
monkeypatch.setattr(fevalidate, "arrange", lambda f: (called.setdefault("flow", f), "arranged"))
|
|
184
|
+
|
|
185
|
+
class Srv:
|
|
186
|
+
def put(self, path, body):
|
|
187
|
+
self.body = body
|
|
188
|
+
|
|
189
|
+
def get(self, path, query=None):
|
|
190
|
+
return {"flow": {"isValid": True}}
|
|
191
|
+
out = fevalidate.save_flow(Srv(), {"id": "p1"}, flow_id="p1", valid=True)
|
|
192
|
+
assert called and out["layout"] == "arranged"
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_save_keeps_the_canvas_when_asked(monkeypatch):
|
|
196
|
+
from tools.procesio.handlers import fevalidate
|
|
197
|
+
monkeypatch.setenv("PROCESIO_KEEP_LAYOUT", "1")
|
|
198
|
+
monkeypatch.setattr(fevalidate, "arrange", lambda f: (_ for _ in ()).throw(AssertionError("must not arrange")))
|
|
199
|
+
|
|
200
|
+
class Srv:
|
|
201
|
+
def put(self, path, body):
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
def get(self, path, query=None):
|
|
205
|
+
return {"flow": {"isValid": True}}
|
|
206
|
+
out = fevalidate.save_flow(Srv(), {"id": "p1"}, flow_id="p1", valid=True)
|
|
207
|
+
assert out["layout"] == "kept"
|