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,83 @@
|
|
|
1
|
+
"""The SQL formatter may move whitespace and nothing else.
|
|
2
|
+
|
|
3
|
+
The formatter exists so a Query Store node is readable in the designer, and a Query Store node
|
|
4
|
+
IS its statement - so a formatter that could alter one would be trading correctness for looks.
|
|
5
|
+
These tests pin the guarantee rather than the cosmetics: same tokens, same order, idempotent,
|
|
6
|
+
and hands the input back whenever it cannot prove that.
|
|
7
|
+
"""
|
|
8
|
+
from tools.procesio.sqlformat import SINGLE_LINE_LIMIT, format_sql, is_unreadable, _tokens
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_one_line_statement_is_laid_out():
|
|
12
|
+
out = format_sql("SELECT a, b FROM t WHERE x = 1 AND y = 2")
|
|
13
|
+
assert out.splitlines() == ["SELECT a, b", "FROM t", "WHERE x = 1", "AND y = 2"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_only_whitespace_changes():
|
|
17
|
+
sql = ("WITH c AS (SELECT MAX(n) AS n FROM t WHERE k = 'a') "
|
|
18
|
+
"SELECT p.id, q.v FROM p JOIN q ON q.id = p.id WHERE p.n > 0 ORDER BY p.id")
|
|
19
|
+
assert _tokens(format_sql(sql)) == _tokens(sql)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_formatting_is_idempotent():
|
|
23
|
+
sql = "SELECT a FROM t WHERE b = 1 AND c = 2 ORDER BY a"
|
|
24
|
+
once = format_sql(sql)
|
|
25
|
+
assert format_sql(once) == once
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_a_keyword_inside_a_string_literal_is_left_alone():
|
|
29
|
+
sql = "UPDATE t SET msg = 'select from where and or' WHERE id = 1"
|
|
30
|
+
out = format_sql(sql)
|
|
31
|
+
assert "'select from where and or'" in out
|
|
32
|
+
assert _tokens(out) == _tokens(sql)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_a_doubled_quote_inside_a_literal_survives():
|
|
36
|
+
sql = "SELECT 'it''s fine, and from where' AS s FROM t WHERE a = 1"
|
|
37
|
+
out = format_sql(sql)
|
|
38
|
+
assert "'it''s fine, and from where'" in out
|
|
39
|
+
assert _tokens(out) == _tokens(sql)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_placeholders_and_chips_are_opaque():
|
|
43
|
+
sql = "SELECT <%0%> FROM {{ds:Settings}} WHERE {{col:Settings.Key}} = @k AND <%1%> IS NULL"
|
|
44
|
+
out = format_sql(sql)
|
|
45
|
+
for token in ("<%0%>", "{{ds:Settings}}", "{{col:Settings.Key}}", "<%1%>", "@k"):
|
|
46
|
+
assert token in out
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_already_multiline_sql_is_left_exactly_as_the_author_wrote_it():
|
|
50
|
+
sql = "SELECT a\n FROM t\n WHERE b = 1"
|
|
51
|
+
assert format_sql(sql) == sql
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_blank_and_non_string_inputs_pass_through():
|
|
55
|
+
assert format_sql("") == ""
|
|
56
|
+
assert format_sql(None) is None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_nested_parentheses_indent():
|
|
60
|
+
out = format_sql("SELECT (SELECT x FROM u WHERE u.id = t.id) AS v FROM t")
|
|
61
|
+
assert any(line.startswith(" ") for line in out.splitlines())
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_is_unreadable_only_fires_on_a_long_single_line():
|
|
65
|
+
assert is_unreadable("SELECT " + "a" * SINGLE_LINE_LIMIT)
|
|
66
|
+
assert not is_unreadable("SELECT a FROM t")
|
|
67
|
+
assert not is_unreadable("SELECT " + "a" * SINGLE_LINE_LIMIT + "\nFROM t")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_the_builder_refuses_a_long_one_line_script():
|
|
71
|
+
"""SQL gets laid out; a script gets refused, because rewriting code could change it."""
|
|
72
|
+
import pytest
|
|
73
|
+
|
|
74
|
+
import tools.procesio.dto.process.builder as pb
|
|
75
|
+
|
|
76
|
+
long_line = "var x = 1; " * 40 # ~440 characters, one line
|
|
77
|
+
cfg = {"title": "t",
|
|
78
|
+
"variables": [{"name": "out", "type": "string", "direction": "output"}],
|
|
79
|
+
"actions": [{"id": "n", "action": "Node",
|
|
80
|
+
"params": {"Code": long_line, "Single Result": {"var": "out"}}}]}
|
|
81
|
+
with pytest.raises(Exception) as e:
|
|
82
|
+
pb.build(cfg, {"var_ids": {"out": "22222222-2222-2222-2222-222222222222"}})
|
|
83
|
+
assert "ONE line" in str(e.value)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""SQL-action parameterization (tools.procesio.flowmodel.sqlparam) — pure-logic unit tests."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from tools.procesio.flowmodel import sqlparam
|
|
5
|
+
|
|
6
|
+
CRED = "45a1dd18-9d06-47cf-8a7b-7732447264af"
|
|
7
|
+
SQL = "EXEC dbo.sp_Foo\n @A = N'<%0%>',\n @B = N'<%1%>',\n @TopN = 5"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _inline_eq_node():
|
|
11
|
+
"""An 'Execute Query' node that inlines two values as N'<%0%>' / N'<%1%>' (the anti-pattern)."""
|
|
12
|
+
return {
|
|
13
|
+
"id": "n1", "actionName": "Get X", "actionTemplateName": "Execute Query",
|
|
14
|
+
"templateId": sqlparam.EQ_TEMPLATE_ID,
|
|
15
|
+
"customData": {"configuration": [{"settings": [
|
|
16
|
+
{"id": sqlparam.PID_CRED, "type": "credentials", "value": CRED},
|
|
17
|
+
{"id": sqlparam.PID_SIDEPANEL, "type": "side-pannel", "value": [
|
|
18
|
+
{"id": sqlparam.PID_QUERY, "label": "Query", "type": "code-editor",
|
|
19
|
+
"language": "sql", "value": SQL},
|
|
20
|
+
]},
|
|
21
|
+
]}]},
|
|
22
|
+
"parameters": [
|
|
23
|
+
{"tabPropertyId": sqlparam.PID_CRED, "value": CRED},
|
|
24
|
+
{"tabPropertyId": sqlparam.PID_QUERY, "value": SQL,
|
|
25
|
+
"variable": [{"id": 0, "variableId": "aaaaaaaa-0000-0000-0000-000000000000", "attribute": None},
|
|
26
|
+
{"id": 1, "variableId": "bbbbbbbb-0000-0000-0000-000000000000", "attribute": None}]},
|
|
27
|
+
],
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_scan_flags_inline():
|
|
32
|
+
rows = sqlparam.scan({"actions": [_inline_eq_node()]})
|
|
33
|
+
assert rows == [{"actionName": "Get X", "id": "n1", "template": "Execute Query", "inline": True}]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_parameterize_rewrites_sql_and_builds_binding():
|
|
37
|
+
node = _inline_eq_node()
|
|
38
|
+
ok, msg = sqlparam.parameterize_node(node)
|
|
39
|
+
assert ok and "@p0" in msg and "@p1" in msg
|
|
40
|
+
|
|
41
|
+
qp = next(p for p in node["parameters"] if isinstance(p["value"], str) and "EXEC" in p["value"])
|
|
42
|
+
assert "<%" not in qp["value"] # no inline placeholders left
|
|
43
|
+
assert "@p0" in qp["value"] and "@p1" in qp["value"] # named params
|
|
44
|
+
assert "@TopN = 5" in qp["value"] # literal stays inline
|
|
45
|
+
assert "variable" not in qp # inline var-map removed
|
|
46
|
+
|
|
47
|
+
bp = next(p for p in node["parameters"] if p["tabPropertyId"] == sqlparam.PID_BIND)
|
|
48
|
+
assert [e["destination"]["value"] for e in bp["value"]] == ["p0", "p1"]
|
|
49
|
+
assert bp["value"][0]["source"]["variable"][0]["variableId"] == "aaaaaaaa-0000-0000-0000-000000000000"
|
|
50
|
+
|
|
51
|
+
sub = node["customData"]["configuration"][0]["settings"][1]["value"]
|
|
52
|
+
assert any(s.get("id") == sqlparam.PID_BIND and s.get("type") == "map-parameters" for s in sub)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_parameterize_is_idempotent():
|
|
56
|
+
node = _inline_eq_node()
|
|
57
|
+
assert sqlparam.parameterize_node(node)[0] is True
|
|
58
|
+
assert sqlparam.parameterize_node(node)[0] is False # already parameterized
|
|
59
|
+
assert sqlparam.scan({"actions": [node]})[0]["inline"] is False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_attribute_path_source():
|
|
63
|
+
node = _inline_eq_node()
|
|
64
|
+
node["parameters"][1]["variable"][0]["attribute"] = {"attributeId": "cccccccc-0000-0000-0000-000000000000",
|
|
65
|
+
"nextAttribute": None}
|
|
66
|
+
sqlparam.parameterize_node(node)
|
|
67
|
+
bp = next(p for p in node["parameters"] if p["tabPropertyId"] == sqlparam.PID_BIND)
|
|
68
|
+
sub = node["customData"]["configuration"][0]["settings"][1]["value"]
|
|
69
|
+
designer = next(s for s in sub if s.get("id") == sqlparam.PID_BIND)
|
|
70
|
+
assert designer["value"][0]["source"] == "aaaaaaaa-0000-0000-0000-000000000000.cccccccc-0000-0000-0000-000000000000"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_v2_template_migrates_to_execute_query():
|
|
74
|
+
# The real bug: a node LABELLED "Execute Query" but on the deprecated V2 template (a9f851c2). Must be
|
|
75
|
+
# keyed on templateId, not the label — else it keeps V2 (no binding property) -> unbound @params.
|
|
76
|
+
node = _inline_eq_node()
|
|
77
|
+
node["actionTemplateName"] = "Execute Query" # mislabelled
|
|
78
|
+
node["templateId"] = "a9f851c2-e0ba-4fee-9a06-5445ba000001" # ...but really on V2
|
|
79
|
+
node["parameters"][0]["tabPropertyId"] = "a9f851c2-e0ba-4fee-9a06-5445bc000011" # cred (GUID value)
|
|
80
|
+
node["parameters"][1]["tabPropertyId"] = "a9f851c2-e0ba-4fee-9a06-5445bc000014" # query
|
|
81
|
+
ok, _ = sqlparam.parameterize_node(node)
|
|
82
|
+
assert ok
|
|
83
|
+
assert node["templateId"] == sqlparam.EQ_TEMPLATE_ID # migrated to the latest template
|
|
84
|
+
qp = next(p for p in node["parameters"] if isinstance(p["value"], str) and "EXEC" in p["value"])
|
|
85
|
+
assert qp["tabPropertyId"] == sqlparam.PID_QUERY
|
|
86
|
+
cred = next(p for p in node["parameters"] if p["value"] == CRED)
|
|
87
|
+
assert cred["tabPropertyId"] == sqlparam.PID_CRED
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
CMD_SQL = "EXEC xch.Save @Body = N'<%0%>'"
|
|
91
|
+
EC_V1 = "c2760ff2-cd9e-49b4-b751-c05c88e06dac"
|
|
92
|
+
EC_V1_CRED = "6701cb8b-3bde-4c7e-a45d-c37eaeff5e3d"
|
|
93
|
+
EC_V1_SIDE = "fea72099-4718-473d-a091-7749aa38305b"
|
|
94
|
+
EC_V1_CMD = "53896b0d-73a6-412f-9e67-224ca1daae7c"
|
|
95
|
+
EC_V1_OUT = "f3452b3a-2c10-40df-9d34-2d2779dc6ed7"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _inline_command_v1_node(label="Execute Command"):
|
|
99
|
+
"""An inline-SQL node on the DEPRECATED 'Execute Command V1' template. Note the label says
|
|
100
|
+
'Execute Command' while templateId is V1 - the real-world shape, and why the family is keyed on
|
|
101
|
+
templateId. V1 has no Parameters config tab and no Time Out."""
|
|
102
|
+
return {
|
|
103
|
+
"id": "n2", "actionName": "save rates to DB", "actionTemplateName": label,
|
|
104
|
+
"templateId": EC_V1,
|
|
105
|
+
"customData": {"configuration": [{"settings": [
|
|
106
|
+
{"id": EC_V1_CRED, "type": "credentials", "value": CRED},
|
|
107
|
+
{"id": EC_V1_SIDE, "type": "side-pannel", "value": [
|
|
108
|
+
{"id": EC_V1_CMD, "label": "Command", "type": "code-editor",
|
|
109
|
+
"language": "sql", "value": CMD_SQL},
|
|
110
|
+
{"id": EC_V1_OUT, "label": "Output", "type": "number", "value": None},
|
|
111
|
+
]},
|
|
112
|
+
]}]},
|
|
113
|
+
"parameters": [
|
|
114
|
+
{"tabPropertyId": EC_V1_CRED, "value": CRED},
|
|
115
|
+
{"tabPropertyId": EC_V1_CMD, "value": CMD_SQL,
|
|
116
|
+
"variable": [{"id": 0, "variableId": "dddddddd-0000-0000-0000-000000000000", "attribute": None}]},
|
|
117
|
+
{"tabPropertyId": EC_V1_OUT, "value": "<%1%>",
|
|
118
|
+
"variable": [{"id": 1, "variableId": "eeeeeeee-0000-0000-0000-000000000000", "attribute": None}]},
|
|
119
|
+
],
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_family_is_keyed_on_templateid_not_the_label():
|
|
124
|
+
assert sqlparam.family_of(_inline_command_v1_node())[0] == sqlparam.EC_TEMPLATE
|
|
125
|
+
assert sqlparam.family_of(_inline_eq_node())[0] == sqlparam.EQ_TEMPLATE
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_command_binds_its_own_parameters_tab_not_the_query_one():
|
|
129
|
+
"""The bug this guards: writing the Execute QUERY bind id onto a Command node leaves every
|
|
130
|
+
@param unbound at runtime, silently."""
|
|
131
|
+
node = _inline_command_v1_node()
|
|
132
|
+
assert sqlparam.bind_pid(node) == sqlparam.EC_PID_BIND
|
|
133
|
+
assert sqlparam.EC_PID_BIND != sqlparam.PID_BIND
|
|
134
|
+
ok, _ = sqlparam.parameterize_node(node)
|
|
135
|
+
assert ok
|
|
136
|
+
assert any(p["tabPropertyId"] == sqlparam.EC_PID_BIND for p in node["parameters"])
|
|
137
|
+
assert not any(p["tabPropertyId"] == sqlparam.PID_BIND for p in node["parameters"])
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_command_v1_migrates_to_current_command_template():
|
|
141
|
+
node = _inline_command_v1_node()
|
|
142
|
+
sqlparam.parameterize_node(node)
|
|
143
|
+
assert node["templateId"] == sqlparam.EC_TEMPLATE_ID
|
|
144
|
+
assert node["actionTemplateName"] == sqlparam.EC_TEMPLATE
|
|
145
|
+
ids = {p["tabPropertyId"] for p in node["parameters"]}
|
|
146
|
+
assert sqlparam.EC_PID_CRED in ids and sqlparam.EC_PID_COMMAND in ids and sqlparam.EC_PID_OUTPUT in ids
|
|
147
|
+
assert not (ids & {EC_V1_CRED, EC_V1_CMD, EC_V1_OUT}) # no legacy id left behind
|
|
148
|
+
side = node["customData"]["configuration"][0]["settings"][1]
|
|
149
|
+
assert side["id"] == sqlparam.EC_PID_SIDEPANEL
|
|
150
|
+
assert {s["id"] for s in side["value"]} >= {sqlparam.EC_PID_COMMAND, sqlparam.EC_PID_OUTPUT}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_migration_seeds_the_required_timeout_the_legacy_template_lacked():
|
|
154
|
+
node = _inline_command_v1_node()
|
|
155
|
+
sqlparam.parameterize_node(node)
|
|
156
|
+
tp = next(p for p in node["parameters"] if p["tabPropertyId"] == sqlparam.EC_PID_TIMEOUT)
|
|
157
|
+
assert 60 <= int(tp["value"]) <= 1800
|
|
158
|
+
side = node["customData"]["configuration"][0]["settings"][1]["value"]
|
|
159
|
+
assert any(s["id"] == sqlparam.EC_PID_TIMEOUT for s in side)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def test_command_sql_is_rewritten_and_the_variable_moves_to_the_binding():
|
|
163
|
+
node = _inline_command_v1_node()
|
|
164
|
+
sqlparam.parameterize_node(node)
|
|
165
|
+
qp = next(p for p in node["parameters"] if p["tabPropertyId"] == sqlparam.EC_PID_COMMAND)
|
|
166
|
+
assert qp["value"] == "EXEC xch.Save @Body = @p0"
|
|
167
|
+
assert "variable" not in qp
|
|
168
|
+
bp = next(p for p in node["parameters"] if p["tabPropertyId"] == sqlparam.EC_PID_BIND)
|
|
169
|
+
assert bp["value"][0]["destination"]["value"] == "p0"
|
|
170
|
+
assert bp["value"][0]["source"]["variable"][0]["variableId"] == "dddddddd-0000-0000-0000-000000000000"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def test_command_parameterize_is_idempotent():
|
|
174
|
+
node = _inline_command_v1_node()
|
|
175
|
+
assert sqlparam.parameterize_node(node)[0] is True
|
|
176
|
+
assert sqlparam.parameterize_node(node)[0] is False
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_migration_refreshes_labels_to_the_current_template_wording():
|
|
180
|
+
node = _inline_command_v1_node()
|
|
181
|
+
sqlparam.parameterize_node(node)
|
|
182
|
+
settings = node["customData"]["configuration"][0]["settings"]
|
|
183
|
+
cred = next(s for s in settings if s["id"] == sqlparam.EC_PID_CRED)
|
|
184
|
+
assert cred["label"] == "Select Database Server" # was the V1 'Select SQL credentials'
|
|
185
|
+
side = next(s for s in settings if s["id"] == sqlparam.EC_PID_SIDEPANEL)
|
|
186
|
+
assert side["label"] == "Execute Command"
|
|
187
|
+
assert {s["label"] for s in side["value"] if s["id"] == sqlparam.EC_PID_COMMAND} == {"Command"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""The process builder must BLOCK frozen/superseded action version pins (e.g.
|
|
2
|
+
"Call API v3") and point at the live/latest action, unless --force pins one
|
|
3
|
+
intentionally. Guards against silently building on an old action generation.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import itertools
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from tools.procesio.dto.process import builder as pb
|
|
12
|
+
from tools.procesio.errors import UsageError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _ctx(force: bool = False):
|
|
16
|
+
counter = itertools.count(1)
|
|
17
|
+
ctx = {"new_id": lambda: f"00000000-0000-0000-0000-{next(counter):012d}"}
|
|
18
|
+
if force:
|
|
19
|
+
ctx["_force"] = True
|
|
20
|
+
return ctx
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _cfg(action: str):
|
|
24
|
+
return {"title": "t", "variables": [{"name": "q", "type": "string"}],
|
|
25
|
+
"actions": [{"id": "c", "action": action,
|
|
26
|
+
"params": {"Verb": "3ab385bd-f8ae-b641-9176-e7db886aec01"}}]}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.mark.parametrize("action", ["Call API v1", "Call API v2", "Call API v3"])
|
|
30
|
+
def test_superseded_call_api_is_blocked(action):
|
|
31
|
+
with pytest.raises(UsageError, match="superseded"):
|
|
32
|
+
pb.build(_cfg(action), _ctx())
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_block_message_names_the_latest_action():
|
|
36
|
+
with pytest.raises(UsageError, match=r"Call API"):
|
|
37
|
+
pb.build(_cfg("Call API v3"), _ctx())
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_force_allows_pinning_the_old_version():
|
|
41
|
+
# --force (ctx["_force"]) is the escape hatch for an intentional pin.
|
|
42
|
+
dto = pb.build(_cfg("Call API v3"), _ctx(force=True))
|
|
43
|
+
assert dto["Actions"], "forced build should proceed past the superseded guard"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_latest_call_api_builds_cleanly():
|
|
47
|
+
dto = pb.build(_cfg("Call API"), _ctx())
|
|
48
|
+
assert any((a.get("ActionTemplateName") or "").strip() == "Call API" for a in dto["Actions"])
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_execute_query_v2_is_blocked():
|
|
52
|
+
# Guard fires before catalog resolution, so it applies even to versioned SQL pins.
|
|
53
|
+
with pytest.raises(UsageError, match="Execute Query"):
|
|
54
|
+
pb.build({"title": "t", "actions": [{"id": "e", "action": "Execute Query V2"}]}, _ctx())
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Optimistic-concurrency guard shared by the surgical write actions.
|
|
2
|
+
|
|
3
|
+
A surgical action reads the live DTO, changes one field, and PUTs the whole thing
|
|
4
|
+
back — last-write-wins. The guard re-reads right before the PUT and refuses to
|
|
5
|
+
overwrite if the resource's update-token moved since it was read. It is INERT when
|
|
6
|
+
the resource exposes no update-timestamp/version field (a safe no-op, never a false
|
|
7
|
+
conflict), which is why the token-less fakes in the other suites are unaffected.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from tools.procesio import main
|
|
14
|
+
from tools.procesio.client import ProcesioClient
|
|
15
|
+
from tools.procesio.errors import UsageError
|
|
16
|
+
from tools.procesio.handlers import common
|
|
17
|
+
from tools.procesio.tests.conftest import FakeResp, FakeSession
|
|
18
|
+
|
|
19
|
+
APIKEY = {"type": "apikey", "key": "N", "value": "V"}
|
|
20
|
+
KEY = "test-passphrase"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# -- guard unit ---------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
def test_concurrency_token_matches_common_fields_case_insensitively():
|
|
26
|
+
assert common.concurrency_token({"updatedOn": "2026-08-07T10:00:00Z"})[1] == "2026-08-07T10:00:00Z"
|
|
27
|
+
assert common.concurrency_token({"Version": 7})[1] == 7
|
|
28
|
+
assert common.concurrency_token({"name": "x", "data": {}}) is None # no token field
|
|
29
|
+
assert common.concurrency_token("not a dict") is None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_guard_is_inert_without_a_token_and_never_refetches():
|
|
33
|
+
calls = []
|
|
34
|
+
def refetch():
|
|
35
|
+
calls.append(1); return {}
|
|
36
|
+
out = common.guard_unchanged(refetch, {"name": "no token here"}, force=False)
|
|
37
|
+
assert out["checked"] is False and "inactive" in out["note"]
|
|
38
|
+
assert calls == [] # no extra GET when inert
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_guard_passes_when_the_token_is_unchanged():
|
|
42
|
+
base = {"updatedOn": "T1"}
|
|
43
|
+
out = common.guard_unchanged(lambda: {"updatedOn": "T1"}, base, force=False)
|
|
44
|
+
assert out == {"checked": True, "token": "T1"}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_guard_aborts_when_the_token_moved():
|
|
48
|
+
base = {"updatedOn": "T1"}
|
|
49
|
+
with pytest.raises(UsageError, match="changed since it was read"):
|
|
50
|
+
common.guard_unchanged(lambda: {"updatedOn": "T2"}, base, force=False)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_force_skips_the_check_and_does_not_refetch():
|
|
54
|
+
calls = []
|
|
55
|
+
def refetch():
|
|
56
|
+
calls.append(1); return {"updatedOn": "T2"}
|
|
57
|
+
out = common.guard_unchanged(refetch, {"updatedOn": "T1"}, force=True)
|
|
58
|
+
assert out["forced"] is True and out["checked"] is False
|
|
59
|
+
assert calls == [] # forced -> no refetch
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# -- integration through form-set-code ---------------------------------------
|
|
63
|
+
|
|
64
|
+
@pytest.fixture(autouse=True)
|
|
65
|
+
def _stub_key(monkeypatch):
|
|
66
|
+
monkeypatch.setattr("tools.procesio.handlers.form_code._code_key", lambda *_a, **_k: KEY)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _call(action, argv, session):
|
|
70
|
+
return main.dispatch(
|
|
71
|
+
action, argv,
|
|
72
|
+
client_builder=lambda prof: ProcesioClient(profile=APIKEY, name="t", session=session))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _form(updated_on):
|
|
76
|
+
"""A form DTO that carries an update token, so the guard is ACTIVE on it."""
|
|
77
|
+
return {"id": "F1", "name": "F", "isPrivate": False, "type": 1, "status": 1,
|
|
78
|
+
"state": True, "assignees": [], "customUrl": None, "updatedOn": updated_on,
|
|
79
|
+
"data": {"code": "", "elements": []}}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_set_code_proceeds_when_the_form_is_unchanged():
|
|
83
|
+
# GET (read) -> GET (guard re-read, same token) -> PUT -> GET (read-back)
|
|
84
|
+
s = FakeSession(queue=[FakeResp(200, _form("T1")), FakeResp(200, _form("T1")),
|
|
85
|
+
FakeResp(200, {})])
|
|
86
|
+
out = _call("form-set-code", ["--id", "F1", "--css", ".x{}"], s)
|
|
87
|
+
assert out["updated"] is True and out["concurrency"] == {"checked": True, "token": "T1"}
|
|
88
|
+
assert [c["method"] for c in s.calls] == ["GET", "GET", "PUT", "GET"]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_set_code_aborts_when_the_form_changed_since_read():
|
|
92
|
+
# GET (read, T1) -> GET (guard re-read, T2) -> abort BEFORE any PUT
|
|
93
|
+
s = FakeSession(queue=[FakeResp(200, _form("T1")), FakeResp(200, _form("T2"))])
|
|
94
|
+
with pytest.raises(UsageError, match="changed since it was read"):
|
|
95
|
+
_call("form-set-code", ["--id", "F1", "--css", ".x{}"], s)
|
|
96
|
+
assert all(c["method"] == "GET" for c in s.calls) # never wrote
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_set_code_force_overwrites_without_re_reading():
|
|
100
|
+
# force -> no guard GET: GET (read) -> PUT -> GET (read-back of what was stored)
|
|
101
|
+
s = FakeSession(queue=[FakeResp(200, _form("T1")), FakeResp(200, {})])
|
|
102
|
+
out = _call("form-set-code", ["--id", "F1", "--css", ".x{}", "--force"], s)
|
|
103
|
+
assert out["updated"] is True and out["concurrency"]["forced"] is True
|
|
104
|
+
assert [c["method"] for c in s.calls] == ["GET", "PUT", "GET"] # single read before the PUT, no guard GET
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# -- integration through rename-actions (the other guarded writer) ------------
|
|
108
|
+
|
|
109
|
+
class _FlowClient:
|
|
110
|
+
"""A process client whose flow token can move between the baseline read and the
|
|
111
|
+
guard's re-read, to exercise rename-actions' concurrency guard."""
|
|
112
|
+
def __init__(self, tokens):
|
|
113
|
+
self.workspace_id = "ws"
|
|
114
|
+
self.profile = {} # unbound -> production designer host
|
|
115
|
+
self._tokens = list(tokens)
|
|
116
|
+
self.i = 0
|
|
117
|
+
self.puts = []
|
|
118
|
+
|
|
119
|
+
def _flow(self):
|
|
120
|
+
tok = self._tokens[min(self.i, len(self._tokens) - 1)]
|
|
121
|
+
self.i += 1
|
|
122
|
+
return {"id": "P", "updatedOn": tok,
|
|
123
|
+
"actions": [{"id": "a1", "actionName": "Node",
|
|
124
|
+
"customData": {"name": "Node"}}]}
|
|
125
|
+
|
|
126
|
+
def get(self, path, query=None):
|
|
127
|
+
return {"flow": self._flow()}
|
|
128
|
+
|
|
129
|
+
def post(self, path, body=None, query=None):
|
|
130
|
+
return {"raw_text": ""}
|
|
131
|
+
|
|
132
|
+
def put(self, path, body=None, query=None):
|
|
133
|
+
self.puts.append(body)
|
|
134
|
+
return {}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _rename_args(force=False):
|
|
138
|
+
from argparse import Namespace
|
|
139
|
+
return Namespace(id="P", workspace_id="ws", profile=None, map='{"a1": "Renamed"}',
|
|
140
|
+
map_file=None, no_validate=True, dry_run=False, force=force)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def test_rename_actions_proceeds_when_the_flow_is_unchanged():
|
|
144
|
+
from tools.procesio.handlers import process_naming as pn
|
|
145
|
+
c = _FlowClient(["T1", "T1"]) # baseline read + guard re-read: same
|
|
146
|
+
out = pn.rename_actions(c, _rename_args())["result"]
|
|
147
|
+
assert out["saved"] is True and out["concurrency"] == {"checked": True, "token": "T1"}
|
|
148
|
+
assert len(c.puts) == 1
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_rename_actions_aborts_when_the_flow_moved():
|
|
152
|
+
from tools.procesio.handlers import process_naming as pn
|
|
153
|
+
c = _FlowClient(["T1", "T2"]) # token moved between read and re-read
|
|
154
|
+
with pytest.raises(UsageError, match="changed since it was read"):
|
|
155
|
+
pn.rename_actions(c, _rename_args())
|
|
156
|
+
assert c.puts == [] # never saved
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Tier-4 ergonomics: inspect-flow, action families, form optionsSource + chainConfig."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import itertools
|
|
5
|
+
|
|
6
|
+
from tools.procesio.flowmodel import families
|
|
7
|
+
from tools.procesio.flowmodel.inspect import inspect
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _flow():
|
|
11
|
+
return {
|
|
12
|
+
"Id": "f1", "Title": "Sample",
|
|
13
|
+
"Variables": [{"Id": "v1", "Name": "items", "Type": 10, "IsRequired": True}],
|
|
14
|
+
"Actions": [
|
|
15
|
+
{"Id": "start", "ActionTemplateName": "Start",
|
|
16
|
+
"CustomData": {"type": "circle"},
|
|
17
|
+
"Ports": [{"SourceId": "start", "DestinationId": "fe", "Type": 0}]},
|
|
18
|
+
{"Id": "fe", "ActionTemplateName": "For Each",
|
|
19
|
+
"CustomData": {"type": "area", "name": "For Each"},
|
|
20
|
+
"Ports": [{"SourceId": "fe", "DestinationId": "api", "Type": 0}]},
|
|
21
|
+
{"Id": "api", "ActionTemplateName": "Call API", "ParentId": "fe",
|
|
22
|
+
"CustomData": {"type": "square"},
|
|
23
|
+
"Ports": [{"SourceId": "api", "DestinationId": "d", "Type": 0}]},
|
|
24
|
+
{"Id": "d", "ActionTemplateName": "Decisional",
|
|
25
|
+
"CustomData": {"type": "diamond"},
|
|
26
|
+
"Ports": [{"SourceId": "d", "DestinationId": "stop", "Type": 0},
|
|
27
|
+
{"SourceId": "d", "DestinationId": "stop2", "Type": 0}]},
|
|
28
|
+
{"Id": "stop", "ActionTemplateName": "Stop", "CustomData": {"type": "circle"}, "Ports": []},
|
|
29
|
+
{"Id": "stop2", "ActionTemplateName": "Stop", "CustomData": {"type": "circle"}, "Ports": []},
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_families_classify():
|
|
35
|
+
assert families.classify("Call API") == "integration"
|
|
36
|
+
assert families.classify("Node") == "scripting"
|
|
37
|
+
assert families.classify("For Each") == "control"
|
|
38
|
+
assert families.classify("Totally Unknown Action") == "other"
|
|
39
|
+
assert families.describe("Call API")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_inspect_counts_and_families():
|
|
43
|
+
r = inspect(_flow())
|
|
44
|
+
assert r["counts"]["actions"] == 6
|
|
45
|
+
assert r["counts"]["decisionals"] == 1
|
|
46
|
+
assert r["counts"]["stops"] == 2
|
|
47
|
+
assert r["counts"]["foreach"] == 1
|
|
48
|
+
assert r["action_families"].get("integration") == 1
|
|
49
|
+
assert r["action_families"].get("control") # start/stop/foreach/decisional
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_inspect_branches():
|
|
53
|
+
r = inspect(_flow())
|
|
54
|
+
assert len(r["branches"]) == 1
|
|
55
|
+
assert r["branches"][0]["cases"] == 2
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_inspect_smells():
|
|
59
|
+
codes = {s["code"] for s in inspect(_flow())["smells"]}
|
|
60
|
+
# Call API inside a For Each, with no error port -> two smells fire
|
|
61
|
+
assert "no_error_port" in codes
|
|
62
|
+
assert "slow_in_loop" in codes
|
|
63
|
+
assert "required_inputs" in codes
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_inspect_variables_contract():
|
|
67
|
+
r = inspect(_flow())
|
|
68
|
+
assert r["variables"]["inputs"] == ["items"]
|
|
69
|
+
assert r["variables"]["required"] == ["items"]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# -- form builder optionsSource + chainConfig --------------------------------
|
|
73
|
+
|
|
74
|
+
def _form_ctx():
|
|
75
|
+
cnt = itertools.count(1)
|
|
76
|
+
return {"new_id": lambda: f"00000000-0000-0000-0000-{next(cnt):012d}"}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _configs(el):
|
|
80
|
+
return {c.get("key"): c.get("value") for c in el.get("configs", [])}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _select(elements, name=None):
|
|
84
|
+
return next(e for e in elements if e.get("type") == "select")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_form_options_source_json():
|
|
88
|
+
from tools.procesio.dto.form import builder as fb
|
|
89
|
+
cfg = {"name": "F", "elements": [
|
|
90
|
+
{"type": "select", "label": "Pick",
|
|
91
|
+
"optionsSource": {"type": "json", "value": [{"label": "A", "value": "a"}]}}]}
|
|
92
|
+
els = fb.build(cfg, _form_ctx())["Data"]["elements"]
|
|
93
|
+
c = _configs(_select(els))
|
|
94
|
+
assert c["sourceType"] == "JSON"
|
|
95
|
+
assert c["sourceValue"] == [{"label": "A", "value": "a"}]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_form_options_source_url():
|
|
99
|
+
from tools.procesio.dto.form import builder as fb
|
|
100
|
+
cfg = {"name": "F", "elements": [
|
|
101
|
+
{"type": "select", "label": "Pick",
|
|
102
|
+
"optionsSource": {"type": "url", "value": "https://x/opts"}}]}
|
|
103
|
+
els = fb.build(cfg, _form_ctx())["Data"]["elements"]
|
|
104
|
+
c = _configs(_select(els))
|
|
105
|
+
assert c["sourceType"] == "URL"
|
|
106
|
+
assert c["sourceValue"] == "https://x/opts"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_form_static_options_unchanged():
|
|
110
|
+
from tools.procesio.dto.form import builder as fb
|
|
111
|
+
cfg = {"name": "F", "elements": [
|
|
112
|
+
{"type": "select", "label": "Pick", "options": ["A", "B"]}]}
|
|
113
|
+
els = fb.build(cfg, _form_ctx())["Data"]["elements"]
|
|
114
|
+
assert _configs(_select(els))["sourceType"] == "static-list"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_form_chainconfig_emitted_only_when_present():
|
|
118
|
+
from tools.procesio.dto.form import builder as fb
|
|
119
|
+
base = {"name": "F", "elements": [{"type": "paragraph", "label": "hi"}]}
|
|
120
|
+
assert "chainConfig" not in fb.build(base, _form_ctx())["Data"]
|
|
121
|
+
chained = {**base, "chainConfig": {"columns": [{"forms": ["a"]}]}}
|
|
122
|
+
data = fb.build(chained, _form_ctx())["Data"]
|
|
123
|
+
assert data["chainConfig"] == {"columns": [{"forms": ["a"]}]}
|