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,199 @@
|
|
|
1
|
+
"""Surgical read/write of ONE element's plain configs on a live form.
|
|
2
|
+
|
|
3
|
+
Third member of the surgical family, after form_code.py (Data.code) and
|
|
4
|
+
form_events.py (one element's event handlers), and it exists for the same reason:
|
|
5
|
+
`form-edit` is a DESIRED-STATE editor that rebuilds the whole DTO from a config,
|
|
6
|
+
so using it to change one paragraph's HTML on a large hand-authored form means
|
|
7
|
+
re-declaring every element or losing them.
|
|
8
|
+
|
|
9
|
+
What this pair covers that the other two do not: the SEMANTIC configs — `label`,
|
|
10
|
+
`placeholder`, `required`, `regex`, `visible`, `tooltip`, `info-text`,
|
|
11
|
+
`defaultValue`. Content and per-field rules belong in the DTO, not in the
|
|
12
|
+
form-level JS layer: a paragraph rewritten from JavaScript is invisible in the
|
|
13
|
+
designer, has to be re-applied on every render, and fights the runtime's own
|
|
14
|
+
MutationObserver.
|
|
15
|
+
|
|
16
|
+
Two invariants this handler holds, both load-bearing (see FORM-DEV-GUIDE/01):
|
|
17
|
+
|
|
18
|
+
1. **It only ever overwrites configs that already exist.** Adding a config key
|
|
19
|
+
would also require a matching data-model attribute whose id equals the new
|
|
20
|
+
config's id; without it the process designer renders raw guids and values
|
|
21
|
+
never flow. Refusing the write is the honest failure — silently creating a
|
|
22
|
+
half-wired config is not.
|
|
23
|
+
2. **Config ids are preserved.** The data-model mirror addresses each attribute
|
|
24
|
+
by the element's own config id, so a fresh id on a rewritten config breaks
|
|
25
|
+
every value path that points at it.
|
|
26
|
+
|
|
27
|
+
`form-set-element-config` always returns the PREVIOUS value of every config it
|
|
28
|
+
touched, so an overwrite is recoverable from the tool output alone.
|
|
29
|
+
"""
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import argparse
|
|
33
|
+
import copy
|
|
34
|
+
import json
|
|
35
|
+
|
|
36
|
+
from tools.procesio.actiondef import ActionDef
|
|
37
|
+
from tools.procesio.dto.form.builder import reconcile_assignees
|
|
38
|
+
from tools.procesio.errors import UsageError
|
|
39
|
+
from tools.procesio.handlers.common import add_force_arg, add_profile_arg, guard_unchanged
|
|
40
|
+
from tools.procesio.handlers.form_code import _fetch, build_put_body
|
|
41
|
+
from tools.procesio.handlers.form_events import _cfg, _find_element
|
|
42
|
+
|
|
43
|
+
# Event configs are a different shape (`{debounce, events:[…]}`) with their own
|
|
44
|
+
# resolution rules — process-variable names to guids, one event per trigger. They
|
|
45
|
+
# go through form-set-element-event, which knows those rules; routing them here
|
|
46
|
+
# would let a caller write a mapping row the designer cannot render.
|
|
47
|
+
def _is_event_key(key: str) -> bool:
|
|
48
|
+
return key.startswith("on") and key.endswith("Events")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _parse_value(raw: str):
|
|
52
|
+
"""JSON first, plain string as the fallback.
|
|
53
|
+
|
|
54
|
+
`--set required=true` should store the boolean, and `--set label=<p>Hi</p>`
|
|
55
|
+
the string. Trying JSON first and falling back covers both without asking the
|
|
56
|
+
caller to quote every scalar.
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
return json.loads(raw)
|
|
60
|
+
except (ValueError, TypeError):
|
|
61
|
+
return raw
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _split_assignment(item: str, label: str) -> tuple[str, str]:
|
|
65
|
+
if "=" not in item:
|
|
66
|
+
raise UsageError(f"--{label} expects key=value, got {item!r}")
|
|
67
|
+
key, _, value = item.partition("=")
|
|
68
|
+
key = key.strip()
|
|
69
|
+
if not key:
|
|
70
|
+
raise UsageError(f"--{label} expects a config key before '=', got {item!r}")
|
|
71
|
+
return key, value
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# -- actions -----------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
def get_element(client, args) -> dict:
|
|
77
|
+
form = _fetch(client, args.id)
|
|
78
|
+
elements = form["data"].get("elements") or []
|
|
79
|
+
el = _find_element(elements, args.element)
|
|
80
|
+
configs = el.get("configs") or []
|
|
81
|
+
wanted = set(args.key or [])
|
|
82
|
+
return {
|
|
83
|
+
"form_id": args.id,
|
|
84
|
+
"element_id": el.get("id"),
|
|
85
|
+
"type": el.get("type"),
|
|
86
|
+
"parent_id": el.get("parentId"),
|
|
87
|
+
"section": el.get("section"),
|
|
88
|
+
"configs": {
|
|
89
|
+
c.get("key"): c.get("value")
|
|
90
|
+
for c in configs
|
|
91
|
+
if not wanted or c.get("key") in wanted
|
|
92
|
+
},
|
|
93
|
+
"config_keys": [c.get("key") for c in configs],
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def set_element_config(client, args) -> dict:
|
|
98
|
+
updates: dict[str, object] = {}
|
|
99
|
+
for item in args.set or []:
|
|
100
|
+
key, raw = _split_assignment(item, "set")
|
|
101
|
+
updates[key] = _parse_value(raw)
|
|
102
|
+
for item in args.set_file or []:
|
|
103
|
+
key, path = _split_assignment(item, "set-file")
|
|
104
|
+
with open(path, encoding="utf-8") as f:
|
|
105
|
+
updates[key] = f.read()
|
|
106
|
+
if not updates:
|
|
107
|
+
raise UsageError("nothing to set: pass --set key=value and/or --set-file key=path")
|
|
108
|
+
|
|
109
|
+
bad = sorted(k for k in updates if _is_event_key(k))
|
|
110
|
+
if bad:
|
|
111
|
+
raise UsageError(
|
|
112
|
+
f"{', '.join(bad)} are event configs; wire them with form-set-element-event, "
|
|
113
|
+
f"which resolves process-variable names to guids and enforces one event per trigger")
|
|
114
|
+
|
|
115
|
+
form = _fetch(client, args.id)
|
|
116
|
+
elements = form["data"].get("elements") or []
|
|
117
|
+
el = _find_element(elements, args.element)
|
|
118
|
+
|
|
119
|
+
# Refuse BEFORE writing anything: a config this element does not carry has no
|
|
120
|
+
# data-model attribute behind it, and creating one here would wire it only
|
|
121
|
+
# half-way (see the module docstring).
|
|
122
|
+
missing = sorted(k for k in updates if _cfg(el, k) is None)
|
|
123
|
+
if missing:
|
|
124
|
+
raise UsageError(
|
|
125
|
+
f"element {args.element!r} has no config {', '.join(missing)}; "
|
|
126
|
+
f"it carries {', '.join(c.get('key') for c in el.get('configs') or [])}")
|
|
127
|
+
|
|
128
|
+
before = copy.deepcopy(elements)
|
|
129
|
+
previous = {}
|
|
130
|
+
for key, value in updates.items():
|
|
131
|
+
c = _cfg(el, key)
|
|
132
|
+
previous[key] = c.get("value")
|
|
133
|
+
c["value"] = value # the config's own id is preserved
|
|
134
|
+
|
|
135
|
+
# Changing an assignee/approver (or a dynamic row's approval steps) changes who the form
|
|
136
|
+
# routes to; the designer would re-derive the top-level Assignees on save, so do the same.
|
|
137
|
+
assignees, routing = reconcile_assignees(form.get("assignees") or [], before, elements)
|
|
138
|
+
|
|
139
|
+
result = {
|
|
140
|
+
"form_id": args.id,
|
|
141
|
+
"element_id": el.get("id"),
|
|
142
|
+
"type": el.get("type"),
|
|
143
|
+
"set": updates,
|
|
144
|
+
"previous": previous,
|
|
145
|
+
"elements": len(elements),
|
|
146
|
+
}
|
|
147
|
+
if routing:
|
|
148
|
+
result["assignees"] = routing
|
|
149
|
+
if args.dry_run:
|
|
150
|
+
return {"dry_run": True, **result}
|
|
151
|
+
|
|
152
|
+
guard = guard_unchanged(lambda: _fetch(client, args.id), form, force=args.force)
|
|
153
|
+
client.put("/api/FormTemplate", build_put_body(form, data=form["data"],
|
|
154
|
+
assignees=assignees if routing else None))
|
|
155
|
+
return {"updated": True, "concurrency": guard, **result}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _get_args(p: argparse.ArgumentParser) -> None:
|
|
159
|
+
add_profile_arg(p)
|
|
160
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
161
|
+
p.add_argument("--element", required=True,
|
|
162
|
+
help="element id, or its `name` config as the designer shows it")
|
|
163
|
+
p.add_argument("--key", action="append",
|
|
164
|
+
help="only return this config key (repeatable; default: all)")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _set_args(p: argparse.ArgumentParser) -> None:
|
|
168
|
+
add_profile_arg(p)
|
|
169
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
170
|
+
p.add_argument("--element", required=True,
|
|
171
|
+
help="element id, or its `name` config as the designer shows it")
|
|
172
|
+
p.add_argument("--set", action="append",
|
|
173
|
+
help="key=value to write (repeatable); the value is parsed as JSON "
|
|
174
|
+
"when it parses, otherwise stored as a plain string. A value that "
|
|
175
|
+
"LOOKS like JSON (true/42/[..]) is stored as that type — for a "
|
|
176
|
+
"literal string that looks like JSON, use --set-file (always a string)")
|
|
177
|
+
p.add_argument("--set-file", dest="set_file", action="append",
|
|
178
|
+
help="key=path to write a config's value from a file (repeatable) — "
|
|
179
|
+
"for long HTML labels")
|
|
180
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
181
|
+
help="report the change (and the previous values) without writing")
|
|
182
|
+
add_force_arg(p)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
ACTIONS = {
|
|
186
|
+
"form-get-element": ActionDef(
|
|
187
|
+
func=get_element, add_args=_get_args, needs_client=True,
|
|
188
|
+
description="Read one element's configs from a live form (id or name).",
|
|
189
|
+
),
|
|
190
|
+
"form-set-element-config": ActionDef(
|
|
191
|
+
func=set_element_config, add_args=_set_args, needs_client=True,
|
|
192
|
+
description="Set one element's plain configs in place (surgical: only that "
|
|
193
|
+
"element's config values change, ids preserved; returns the previous "
|
|
194
|
+
"values). Event configs go through form-set-element-event. Changing who "
|
|
195
|
+
"works or approves a step (assignee/approver configs, a dynamic row's "
|
|
196
|
+
"approvalSteps) re-derives the form's top-level Assignees as the designer "
|
|
197
|
+
"would, reported under `assignees`; any other change leaves it untouched.",
|
|
198
|
+
),
|
|
199
|
+
}
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
"""Surgical read/write of ONE element's event list on a live form.
|
|
2
|
+
|
|
3
|
+
Companion to form_code.py, and it exists for the same reason: `form-edit` is a
|
|
4
|
+
DESIRED-STATE editor that rebuilds the whole DTO from a config, so using it to
|
|
5
|
+
wire a single button or upload on a large hand-authored form means re-declaring
|
|
6
|
+
every element or losing them. These actions do a read-modify-write on the LIVE
|
|
7
|
+
DTO and touch ONLY the target element's event config.
|
|
8
|
+
|
|
9
|
+
The event model (see PROCESIO-RESOURCE-MODEL-NOTES.md): each element carries
|
|
10
|
+
per-trigger configs — `onClickEvents`, `onInputEvents`, `onStepChangeEvents`,
|
|
11
|
+
`onPaginationChangedEvents` — whose value is `{debounce, events:[…]}`. A fresh
|
|
12
|
+
element has the key present with a `null` value, which is what "no handler" looks
|
|
13
|
+
like; it is not an error and not a missing field.
|
|
14
|
+
|
|
15
|
+
The trap this action exists to prevent: in a RUN_PROCESS `inputMap`/`outputMap`
|
|
16
|
+
the PROCESS VARIABLE GUID belongs on the LEFT and the form value-path on the
|
|
17
|
+
right. A variable NAME on the left is accepted by the API but the designer then
|
|
18
|
+
renders raw guids and the launch 400s, so names are resolved to guids here and an
|
|
19
|
+
unknown name fails before anything is written.
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import argparse
|
|
24
|
+
import copy
|
|
25
|
+
import json
|
|
26
|
+
import uuid
|
|
27
|
+
|
|
28
|
+
from tools.procesio.actiondef import ActionDef
|
|
29
|
+
from tools.procesio.client import VARIABLES_ONLY
|
|
30
|
+
from tools.procesio.errors import UsageError
|
|
31
|
+
from tools.procesio.handlers.common import add_force_arg, add_profile_arg, guard_unchanged
|
|
32
|
+
from tools.procesio.handlers.form_code import _fetch, build_put_body
|
|
33
|
+
|
|
34
|
+
# Trigger -> (config key, event type) comes from the DTO builder's own maps, which
|
|
35
|
+
# were verified against the ui-builder source. Re-deriving them here would let the
|
|
36
|
+
# two drift, and a wrong event type is silently accepted by the API.
|
|
37
|
+
from tools.procesio.dto.form.builder import _EVENT_KEY, _EVENT_TYPE, _golden # noqa: E402
|
|
38
|
+
|
|
39
|
+
# The value-path rule itself is shared with the builder, so the action that CHECKS a path and
|
|
40
|
+
# the one that WRITES one cannot disagree.
|
|
41
|
+
from tools.procesio.dto.form import fieldpath # noqa: E402
|
|
42
|
+
|
|
43
|
+
ACTIONS_ALLOWED = ("RUN_PROCESS", "RUN_JAVASCRIPT", "RUN_DATA_STORE_OPERATION")
|
|
44
|
+
|
|
45
|
+
# EventAction.RUN_DATA_STORE_OPERATION (ui-builder model/config/events/index.ts): a
|
|
46
|
+
# form element triggers a Data Store operation, the same way RUN_PROCESS triggers a
|
|
47
|
+
# process. config = EventRunDataStoreOperationConfig {dataStoreId, operation, inputMap,
|
|
48
|
+
# outputMap, filters?, areFiltersConfigured?}. operation = DataStoreOperation
|
|
49
|
+
# READ/ADD/UPDATE/DELETE; filters apply to every op except ADD
|
|
50
|
+
# (dataStoreOperationSupportsFilters). The operation wire encoding (string vs numeric)
|
|
51
|
+
# must be re-verified live — pass a numeric operation via --config if the platform
|
|
52
|
+
# rejects the name. See PROCESIO-RESOURCE-MODEL-NOTES.md.
|
|
53
|
+
_DATA_STORE_OPS = ("READ", "ADD", "UPDATE", "DELETE")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _normalize_op(raw):
|
|
57
|
+
"""Accept an operation as a DataStoreOperation name (case-insensitive) or a raw
|
|
58
|
+
value; return the name upper-cased, or the value unchanged if not a known name."""
|
|
59
|
+
if isinstance(raw, str):
|
|
60
|
+
up = raw.strip().upper()
|
|
61
|
+
return up if up in _DATA_STORE_OPS else raw.strip()
|
|
62
|
+
return raw
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _resolve_trigger(on: str) -> tuple[str, str]:
|
|
66
|
+
key = on.strip()
|
|
67
|
+
friendly = key.lower().replace("-", "").replace("_", "")
|
|
68
|
+
if friendly in _EVENT_KEY:
|
|
69
|
+
return _EVENT_KEY[friendly], _EVENT_TYPE[friendly]
|
|
70
|
+
raise UsageError(
|
|
71
|
+
f"unknown trigger {on!r}; use one of {', '.join(sorted(_EVENT_KEY))}")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _cfg(element: dict, key: str):
|
|
75
|
+
for c in element.get("configs") or []:
|
|
76
|
+
if c.get("key") == key:
|
|
77
|
+
return c
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _template_slot(el_type: str, key: str):
|
|
82
|
+
"""(index, config) of `key` in the element type's golden template, or (None, None)."""
|
|
83
|
+
try:
|
|
84
|
+
template = _golden(str(el_type))
|
|
85
|
+
except UsageError:
|
|
86
|
+
return None, None
|
|
87
|
+
for i, c in enumerate(template.get("configs") or []):
|
|
88
|
+
if c.get("key") == key:
|
|
89
|
+
return i, c
|
|
90
|
+
return None, None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _backfill_slot(element: dict, key: str) -> dict:
|
|
94
|
+
"""Add a missing trigger slot to `element`, the way the runtime does on load.
|
|
95
|
+
|
|
96
|
+
An element saved before a trigger existed (every approval control saved before ~Sep
|
|
97
|
+
2025 has no onBefore*/onAfter* slots) carries no config for it. The form runtime
|
|
98
|
+
back-fills missing configs from the element template on every load
|
|
99
|
+
(ui-builder utils/formBuilder/elements.ts::actualizeElements) and the designer persists
|
|
100
|
+
them on its next save, so an absent slot means "old element", not "cannot raise this
|
|
101
|
+
trigger". Only when the TEMPLATE lacks the key is the trigger really unavailable.
|
|
102
|
+
"""
|
|
103
|
+
index, template = _template_slot(element.get("type"), key)
|
|
104
|
+
configs = element.setdefault("configs", [])
|
|
105
|
+
if template is None:
|
|
106
|
+
raise UsageError(
|
|
107
|
+
f"element type {element.get('type')!r} has no {key!r} config, so it cannot raise "
|
|
108
|
+
f"that trigger; available: "
|
|
109
|
+
f"{', '.join(c.get('key', '') for c in configs if 'vent' in c.get('key', ''))}")
|
|
110
|
+
slot = copy.deepcopy(template)
|
|
111
|
+
slot["id"] = str(uuid.uuid4())
|
|
112
|
+
slot["value"] = None
|
|
113
|
+
configs.insert(min(index, len(configs)), slot)
|
|
114
|
+
return slot
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _find_element(elements: list, ref: str) -> dict:
|
|
118
|
+
"""Match by element id first, then by its `name` config (what the designer shows)."""
|
|
119
|
+
for e in elements:
|
|
120
|
+
if e.get("id") == ref:
|
|
121
|
+
return e
|
|
122
|
+
hits = []
|
|
123
|
+
for e in elements:
|
|
124
|
+
c = _cfg(e, "name")
|
|
125
|
+
if c and str(c.get("value") or "").strip() == ref:
|
|
126
|
+
hits.append(e)
|
|
127
|
+
if len(hits) == 1:
|
|
128
|
+
return hits[0]
|
|
129
|
+
if not hits:
|
|
130
|
+
raise UsageError(f"no element with id or name {ref!r} on this form")
|
|
131
|
+
raise UsageError(f"{len(hits)} elements are named {ref!r}; pass the element id instead")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _process_vars(client, process_id: str) -> dict:
|
|
135
|
+
"""{variable name: the variable DTO}. The whole DTO, not just the id, because a map row also
|
|
136
|
+
has to know whether the variable is a LIST - see _is_list_of."""
|
|
137
|
+
body = client.get(f"/api/Projects/{process_id}", VARIABLES_ONLY)
|
|
138
|
+
if isinstance(body, dict) and "flow" not in body and isinstance(body.get("result"), dict):
|
|
139
|
+
body = body["result"]
|
|
140
|
+
flow = body.get("flow") if isinstance(body, dict) else None
|
|
141
|
+
src = flow if isinstance(flow, dict) else (body if isinstance(body, dict) else {})
|
|
142
|
+
return {v.get("name"): v for v in (src.get("variables") or []) if v.get("name")}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _path_of(side):
|
|
146
|
+
"""The attribute chain a caller supplied on this side, if any.
|
|
147
|
+
|
|
148
|
+
A model-typed process variable is mapped one ATTRIBUTE at a time, and the
|
|
149
|
+
chain lives in the row's `path`. Rebuilding the slot without carrying it over
|
|
150
|
+
silently maps the whole object into a single text field instead.
|
|
151
|
+
"""
|
|
152
|
+
return side.get("path") if isinstance(side, dict) else None
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _slot(value, is_left: bool, path=None, is_list: bool = False) -> dict:
|
|
156
|
+
"""One side of a map row, in the shape the DESIGNER writes.
|
|
157
|
+
|
|
158
|
+
Verified against a live form: each side is an OBJECT, not a bare string —
|
|
159
|
+
`{"value": …, "isList": …, "path": …}` — and the two sides differ, the
|
|
160
|
+
process side carrying `path: {}` and the form side `path: null`. Writing bare
|
|
161
|
+
strings produces a row the API accepts but the designer cannot render.
|
|
162
|
+
|
|
163
|
+
`isList` is NOT cosmetic: a list-valued variable mapped with `isList: false` binds the whole
|
|
164
|
+
result set into a single scalar slot, so the form receives nothing and there is no error to
|
|
165
|
+
read. It is taken from the caller when given, else from the process variable being mapped.
|
|
166
|
+
"""
|
|
167
|
+
if isinstance(value, dict) and "value" in value:
|
|
168
|
+
return value # already in wire shape
|
|
169
|
+
default = {} if is_left else None
|
|
170
|
+
return {"value": value, "isList": bool(is_list),
|
|
171
|
+
"path": default if path is None else path}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _is_list_of(side, variable: dict | None) -> bool:
|
|
175
|
+
"""Whether this side of a map row carries a LIST.
|
|
176
|
+
|
|
177
|
+
A caller that states `isList` wins — it may be mapping one attribute out of a list. Otherwise
|
|
178
|
+
the process variable's own `isList` decides, which is what the designer would have written.
|
|
179
|
+
"""
|
|
180
|
+
if isinstance(side, dict) and "isList" in side:
|
|
181
|
+
return bool(side["isList"])
|
|
182
|
+
return bool((variable or {}).get("isList"))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _plain(value):
|
|
186
|
+
return value.get("value") if isinstance(value, dict) else value
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _resolve_maps(config: dict, client, form: dict | None = None) -> dict:
|
|
190
|
+
"""Turn a map's two sides into the designer's object shape, resolving BOTH.
|
|
191
|
+
|
|
192
|
+
Left is a process variable: a NAME becomes its GUID. Right is a form field, and it used
|
|
193
|
+
to pass through untouched — which is why every caller that guessed the value-path format
|
|
194
|
+
wrote a row the platform accepted, the designer rendered, and the control silently
|
|
195
|
+
ignored. With `form` given, the right side is resolved the same way as the left: a field
|
|
196
|
+
NAME is built into its value path, a path is CHECKED against the live form, and anything
|
|
197
|
+
else is refused before a single byte is written.
|
|
198
|
+
"""
|
|
199
|
+
pid = config.get("processId")
|
|
200
|
+
if not pid:
|
|
201
|
+
raise UsageError("RUN_PROCESS config needs a 'processId'")
|
|
202
|
+
names = _process_vars(client, pid)
|
|
203
|
+
live = fieldpath.LiveForm(form) if form is not None else None
|
|
204
|
+
by_id = {v.get("id"): v for v in names.values() if v.get("id")}
|
|
205
|
+
out = dict(config)
|
|
206
|
+
for side in ("inputMap", "outputMap"):
|
|
207
|
+
rows = out.get(side) or []
|
|
208
|
+
fixed = []
|
|
209
|
+
for i, row in enumerate(rows):
|
|
210
|
+
row = dict(row)
|
|
211
|
+
left = _plain(row.get("left"))
|
|
212
|
+
if left in by_id:
|
|
213
|
+
variable = by_id[left] # already a guid
|
|
214
|
+
elif left in names:
|
|
215
|
+
variable = names[left]
|
|
216
|
+
left = variable.get("id")
|
|
217
|
+
else:
|
|
218
|
+
raise UsageError(
|
|
219
|
+
f"{side}: {left!r} is neither a variable id nor a variable name on "
|
|
220
|
+
f"process {pid}. Known variables: {', '.join(sorted(names)) or '(none)'}")
|
|
221
|
+
# Both sides of a row describe the SAME value, so one list-ness governs the pair: the
|
|
222
|
+
# form variable on the right holds whatever the process variable on the left produced.
|
|
223
|
+
is_list = _is_list_of(row.get("left"), variable) or _is_list_of(row.get("right"), variable)
|
|
224
|
+
right = _plain(row.get("right"))
|
|
225
|
+
if live is not None:
|
|
226
|
+
right = live.resolve(right, f"{side} row {i}")
|
|
227
|
+
row["left"] = _slot(left, True, _path_of(row.get("left")), is_list)
|
|
228
|
+
# a form VARIABLE side carries `path: {}` like the process side (as the designer saves it)
|
|
229
|
+
rpath = {} if live is not None and live.is_variable(right) and _path_of(row.get("right")) is None \
|
|
230
|
+
else _path_of(row.get("right"))
|
|
231
|
+
row["right"] = _slot(right, False, rpath, is_list)
|
|
232
|
+
row["id"] = row.get("id", i)
|
|
233
|
+
fixed.append(row)
|
|
234
|
+
out[side] = fixed
|
|
235
|
+
return out
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def set_element_event(client, args) -> dict:
|
|
239
|
+
cfg_key, default_type = _resolve_trigger(args.on)
|
|
240
|
+
action = args.action.strip().upper()
|
|
241
|
+
if action not in ACTIONS_ALLOWED:
|
|
242
|
+
raise UsageError(f"--action must be one of {', '.join(ACTIONS_ALLOWED)}")
|
|
243
|
+
|
|
244
|
+
raw = args.config
|
|
245
|
+
if args.config_file:
|
|
246
|
+
with open(args.config_file, encoding="utf-8") as f:
|
|
247
|
+
raw = f.read()
|
|
248
|
+
if raw:
|
|
249
|
+
try:
|
|
250
|
+
ev_config = json.loads(raw)
|
|
251
|
+
except json.JSONDecodeError as e:
|
|
252
|
+
raise UsageError(f"--config must be valid JSON: {e}") from e
|
|
253
|
+
if not isinstance(ev_config, dict):
|
|
254
|
+
raise UsageError("--config must be a JSON object")
|
|
255
|
+
elif action == "RUN_DATA_STORE_OPERATION":
|
|
256
|
+
ev_config = {} # may be fully specified via --data-store-id / --operation
|
|
257
|
+
else:
|
|
258
|
+
raise UsageError("provide --config '<json>' or --config-file <path>")
|
|
259
|
+
|
|
260
|
+
form = _fetch(client, args.id)
|
|
261
|
+
elements = form["data"].get("elements") or []
|
|
262
|
+
element = _find_element(elements, args.element)
|
|
263
|
+
|
|
264
|
+
if action == "RUN_PROCESS":
|
|
265
|
+
# `form` is the live DTO fetched above: passing it is what lets the form side of each
|
|
266
|
+
# row be resolved and checked, not merely copied.
|
|
267
|
+
ev_config = _resolve_maps(ev_config, client, form) # fails loudly before any write
|
|
268
|
+
# Backfill the canonical RUN_PROCESS config the DTO builder always emits, so a
|
|
269
|
+
# hand-written minimal {processId, inputMap, outputMap} renders configured in the
|
|
270
|
+
# designer and launches — the designer reads these keys and a missing
|
|
271
|
+
# areConditionsConfigured/conditions leaves the event half-wired. setdefault, so a
|
|
272
|
+
# caller that passes its own value always wins.
|
|
273
|
+
ev_config.setdefault("syncRun", True)
|
|
274
|
+
ev_config.setdefault("mapLatestTriggerOnly", False)
|
|
275
|
+
ev_config.setdefault("conditions", [])
|
|
276
|
+
ev_config.setdefault("areConditionsConfigured", True)
|
|
277
|
+
elif action == "RUN_DATA_STORE_OPERATION":
|
|
278
|
+
if getattr(args, "data_store_id", None):
|
|
279
|
+
ev_config["dataStoreId"] = args.data_store_id
|
|
280
|
+
if getattr(args, "operation", None):
|
|
281
|
+
ev_config["operation"] = _normalize_op(args.operation)
|
|
282
|
+
if not ev_config.get("dataStoreId"):
|
|
283
|
+
raise UsageError("RUN_DATA_STORE_OPERATION needs a dataStoreId "
|
|
284
|
+
"(--data-store-id or in --config)")
|
|
285
|
+
if ev_config.get("operation") in (None, ""):
|
|
286
|
+
raise UsageError("RUN_DATA_STORE_OPERATION needs an operation "
|
|
287
|
+
"(--operation READ|ADD|UPDATE|DELETE or in --config)")
|
|
288
|
+
ev_config.setdefault("inputMap", [])
|
|
289
|
+
ev_config.setdefault("outputMap", [])
|
|
290
|
+
# Filters apply to every operation except ADD (dataStoreOperationSupportsFilters).
|
|
291
|
+
if str(ev_config.get("operation")).upper() != "ADD":
|
|
292
|
+
ev_config.setdefault("filters", [])
|
|
293
|
+
ev_config.setdefault("areFiltersConfigured", bool(ev_config.get("filters")))
|
|
294
|
+
elif not ev_config.get("code"):
|
|
295
|
+
raise UsageError("RUN_JAVASCRIPT config needs a 'code' string")
|
|
296
|
+
|
|
297
|
+
slot = _cfg(element, cfg_key)
|
|
298
|
+
backfilled = []
|
|
299
|
+
if slot is None:
|
|
300
|
+
slot = _backfill_slot(element, cfg_key) # refuses when the type has no such slot
|
|
301
|
+
backfilled.append(cfg_key)
|
|
302
|
+
|
|
303
|
+
current = slot.get("value") or {}
|
|
304
|
+
previous = list(current.get("events") or [])
|
|
305
|
+
event = {"id": str(uuid.uuid4()),
|
|
306
|
+
"type": (args.type or default_type),
|
|
307
|
+
"action": action,
|
|
308
|
+
"config": ev_config}
|
|
309
|
+
|
|
310
|
+
# Three ways to combine the new event with the trigger's existing events:
|
|
311
|
+
# --replace-action ACT : replace ONLY events whose action is ACT, keeping the
|
|
312
|
+
# others and their ORDER (the safe O8 recipe — an element
|
|
313
|
+
# commonly carries [RUN_PROCESS, RUN_JAVASCRIPT] on one
|
|
314
|
+
# trigger, and you rarely mean to drop the sibling).
|
|
315
|
+
# --replace : replace ALL events (destructive) — warns when it would
|
|
316
|
+
# discard more than one.
|
|
317
|
+
# (neither) : append.
|
|
318
|
+
replace_action = (args.replace_action or "").strip().upper() or None
|
|
319
|
+
if replace_action and args.replace:
|
|
320
|
+
raise UsageError(
|
|
321
|
+
"pass either --replace (replace ALL events) or --replace-action <ACTION> "
|
|
322
|
+
"(replace only that action's events) — not both")
|
|
323
|
+
if replace_action and replace_action not in ACTIONS_ALLOWED:
|
|
324
|
+
raise UsageError(f"--replace-action must be one of {', '.join(ACTIONS_ALLOWED)}")
|
|
325
|
+
|
|
326
|
+
warning = None
|
|
327
|
+
if replace_action:
|
|
328
|
+
events, inserted = [], False
|
|
329
|
+
for e in previous:
|
|
330
|
+
if str(e.get("action") or "").upper() == replace_action:
|
|
331
|
+
if not inserted: # new event takes the first slot of its kind
|
|
332
|
+
events.append(event)
|
|
333
|
+
inserted = True
|
|
334
|
+
else:
|
|
335
|
+
events.append(e) # a different action survives, in place
|
|
336
|
+
if not inserted:
|
|
337
|
+
events.append(event)
|
|
338
|
+
elif args.replace:
|
|
339
|
+
events = [event]
|
|
340
|
+
if len(previous) > 1:
|
|
341
|
+
discarded = ", ".join(str(e.get("action")) for e in previous)
|
|
342
|
+
warning = (
|
|
343
|
+
f"--replace discarded ALL {len(previous)} existing events on this "
|
|
344
|
+
f"trigger ({discarded}). Elements commonly carry [RUN_PROCESS, "
|
|
345
|
+
f"RUN_JAVASCRIPT] on one trigger; to replace only one action and keep "
|
|
346
|
+
f"the rest (and their order), use --replace-action <ACTION> instead.")
|
|
347
|
+
else:
|
|
348
|
+
events = previous + [event]
|
|
349
|
+
|
|
350
|
+
result = {
|
|
351
|
+
"id": args.id, "element": args.element, "elementId": element.get("id"),
|
|
352
|
+
"trigger": cfg_key, "action": action,
|
|
353
|
+
"previous_events": previous, "event_count": len(events),
|
|
354
|
+
"elements": len(elements),
|
|
355
|
+
"backfilled": backfilled,
|
|
356
|
+
}
|
|
357
|
+
if warning:
|
|
358
|
+
result["warning"] = warning
|
|
359
|
+
if backfilled:
|
|
360
|
+
result["note"] = (
|
|
361
|
+
f"{args.element!r} was saved before its {', '.join(backfilled)} slot existed, so the "
|
|
362
|
+
f"slot was added from the element template (the form runtime and designer do the "
|
|
363
|
+
f"same on load/save); every other config is unchanged.")
|
|
364
|
+
if args.dry_run:
|
|
365
|
+
return {"dry_run": True, "event": event, **result}
|
|
366
|
+
|
|
367
|
+
guard = guard_unchanged(lambda: _fetch(client, args.id), form, force=args.force)
|
|
368
|
+
slot["value"] = {"debounce": current.get("debounce", 0), "events": events}
|
|
369
|
+
client.put("/api/FormTemplate", build_put_body(form, data=form["data"]))
|
|
370
|
+
return {"updated": True, "event": event, "concurrency": guard, **result}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def get_element_events(client, args) -> dict:
|
|
374
|
+
form = _fetch(client, args.id)
|
|
375
|
+
element = _find_element(form["data"].get("elements") or [], args.element)
|
|
376
|
+
out = {}
|
|
377
|
+
for c in element.get("configs") or []:
|
|
378
|
+
k = c.get("key") or ""
|
|
379
|
+
if "vent" in k:
|
|
380
|
+
out[k] = (c.get("value") or {}).get("events") or []
|
|
381
|
+
return {"id": args.id, "element": args.element, "elementId": element.get("id"),
|
|
382
|
+
"type": element.get("type"), "events": out}
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _common(p: argparse.ArgumentParser) -> None:
|
|
386
|
+
add_profile_arg(p)
|
|
387
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
388
|
+
p.add_argument("--element", required=True,
|
|
389
|
+
help="element id, or its designer 'name' (e.g. doccipf)")
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _set_args(p: argparse.ArgumentParser) -> None:
|
|
393
|
+
_common(p)
|
|
394
|
+
p.add_argument("--on", required=True,
|
|
395
|
+
help="trigger: " + " | ".join(sorted(_EVENT_KEY)) + " (case, '-' and '_' "
|
|
396
|
+
"are ignored). A slot missing from an element saved before that "
|
|
397
|
+
"trigger existed is added from the element template and reported "
|
|
398
|
+
"under `backfilled`")
|
|
399
|
+
p.add_argument("--action", required=True,
|
|
400
|
+
help="RUN_PROCESS | RUN_JAVASCRIPT | RUN_DATA_STORE_OPERATION")
|
|
401
|
+
p.add_argument("--config", help="event config as JSON")
|
|
402
|
+
p.add_argument("--data-store-id", dest="data_store_id",
|
|
403
|
+
help="RUN_DATA_STORE_OPERATION: the target data store id")
|
|
404
|
+
p.add_argument("--operation",
|
|
405
|
+
help="RUN_DATA_STORE_OPERATION: READ | ADD | UPDATE | DELETE")
|
|
406
|
+
p.add_argument("--config-file", dest="config_file", help="path to a JSON config file")
|
|
407
|
+
p.add_argument("--type", help="override the event type (default follows the trigger)")
|
|
408
|
+
p.add_argument("--replace", action="store_true",
|
|
409
|
+
help="replace ALL of this trigger's events instead of appending "
|
|
410
|
+
"(destructive; warns when it discards more than one)")
|
|
411
|
+
p.add_argument("--replace-action", dest="replace_action",
|
|
412
|
+
help="replace only this trigger's events whose action is this "
|
|
413
|
+
"(RUN_PROCESS/RUN_JAVASCRIPT), preserving the others and order")
|
|
414
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
415
|
+
help="build the event and report it without writing")
|
|
416
|
+
add_force_arg(p)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
ACTIONS = {
|
|
420
|
+
"form-get-element-events": ActionDef(
|
|
421
|
+
func=get_element_events, add_args=_common, needs_client=True,
|
|
422
|
+
description="List one element's event handlers, by trigger.",
|
|
423
|
+
),
|
|
424
|
+
"form-set-element-event": ActionDef(
|
|
425
|
+
func=set_element_event, add_args=_set_args, needs_client=True,
|
|
426
|
+
description="Wire one element's trigger to RUN_PROCESS / RUN_JAVASCRIPT / "
|
|
427
|
+
"RUN_DATA_STORE_OPERATION in place (surgical: only that element's event "
|
|
428
|
+
"config changes). In a RUN_PROCESS inputMap/outputMap BOTH sides take "
|
|
429
|
+
"NAMES: left = a process variable name, right = a form FIELD name, a form "
|
|
430
|
+
"variable (@Offer_ID), an element config (Paragraph9.label) or a data-model "
|
|
431
|
+
"path (instance.currentUser.email) - each "
|
|
432
|
+
"is resolved to the id/value-path the runtime needs. Do NOT hand-build "
|
|
433
|
+
"the form value path; if you pass one it is CHECKED against the live form "
|
|
434
|
+
"and refused when wrong, because a wrong path is saved without any error "
|
|
435
|
+
"and the control then launches nothing. A DataStore op takes "
|
|
436
|
+
"--data-store-id + --operation. An element saved before the trigger "
|
|
437
|
+
"existed (e.g. an approval control from before Sep 2025, no "
|
|
438
|
+
"onBeforeApprove slot) gets the missing slot added from the element "
|
|
439
|
+
"template, listed in `backfilled`.",
|
|
440
|
+
),
|
|
441
|
+
}
|