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,270 @@
|
|
|
1
|
+
"""form-update — apply an arbitrary change to a LIVE form and save it safely.
|
|
2
|
+
|
|
3
|
+
The canonical GET -> modify -> PUT path for raw form surgery that no narrower
|
|
4
|
+
action covers (change a label, a theme var, a table column header, a select
|
|
5
|
+
option, publish a draft, rename). It fetches the form, deep-merges a caller
|
|
6
|
+
`--data` patch into its `Data`, optionally overrides top-level Name/Status/State,
|
|
7
|
+
and PUTs the accepted PascalCase envelope via `form_code.build_put_body` — the
|
|
8
|
+
only body shape the server accepts (the camelCase GET echo is rejected 403).
|
|
9
|
+
|
|
10
|
+
Unlike `form-edit`, it does NOT rebuild the form from a desired-state config, so
|
|
11
|
+
existing elements/theme/code/logic survive untouched — only what the patch names
|
|
12
|
+
changes. Like the other surgical actions it is a last-write-wins read-modify-write
|
|
13
|
+
guarded by `guard_unchanged` (--force to override); see form_code.py.
|
|
14
|
+
|
|
15
|
+
Merge semantics (deep merge, deliberately NOT RFC-7386): nested objects merge
|
|
16
|
+
recursively; arrays, scalars, and null REPLACE the target value (null sets the key
|
|
17
|
+
to null — it does not delete it). To swap an array wholesale (elements, variables,
|
|
18
|
+
theme) pass the whole new array; to flip one scalar deep in Data pass just that
|
|
19
|
+
key, e.g. --data '{"hideBranding": true}'.
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import argparse
|
|
24
|
+
import json
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
from tools.procesio import formlint
|
|
28
|
+
from tools.procesio.actiondef import ActionDef
|
|
29
|
+
from tools.procesio.errors import UsageError
|
|
30
|
+
from tools.procesio.handlers.common import add_force_arg, add_profile_arg, guard_unchanged
|
|
31
|
+
from tools.procesio.dto.form import addelement
|
|
32
|
+
from tools.procesio.dto.form.builder import reconcile_assignees
|
|
33
|
+
from tools.procesio.handlers.form_code import _fetch, build_put_body
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _deep_merge(target, patch):
|
|
37
|
+
"""Deep-merge `patch` into `target`. Nested dicts merge; arrays/scalars/null replace."""
|
|
38
|
+
if not isinstance(patch, dict) or not isinstance(target, dict):
|
|
39
|
+
return patch
|
|
40
|
+
out = dict(target)
|
|
41
|
+
for k, v in patch.items():
|
|
42
|
+
out[k] = _deep_merge(out.get(k), v) if isinstance(v, dict) else v
|
|
43
|
+
return out
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _load_patch(args) -> dict | None:
|
|
47
|
+
raw = None
|
|
48
|
+
if args.data_file:
|
|
49
|
+
raw = Path(args.data_file).read_text(encoding="utf-8")
|
|
50
|
+
elif args.data:
|
|
51
|
+
raw = args.data
|
|
52
|
+
if raw is None:
|
|
53
|
+
return None
|
|
54
|
+
try:
|
|
55
|
+
patch = json.loads(raw)
|
|
56
|
+
except json.JSONDecodeError as e:
|
|
57
|
+
raise UsageError(f"--data must be valid JSON: {e}") from e
|
|
58
|
+
if not isinstance(patch, dict):
|
|
59
|
+
raise UsageError("--data must be a JSON object (a merge patch for the form's Data)")
|
|
60
|
+
return patch
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def form_update(client, args) -> dict:
|
|
64
|
+
patch = _load_patch(args)
|
|
65
|
+
state = None if args.state is None else (args.state == "true")
|
|
66
|
+
is_private = None if args.is_private is None else (args.is_private == "true")
|
|
67
|
+
if (patch is None and args.name is None and args.status is None
|
|
68
|
+
and state is None and is_private is None):
|
|
69
|
+
raise UsageError(
|
|
70
|
+
"nothing to update: pass --data/--data-file (a Data merge patch) "
|
|
71
|
+
"and/or --name/--status/--state/--is-private"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
form = _fetch(client, args.id)
|
|
75
|
+
existing = dict(form.get("data") or {})
|
|
76
|
+
data = existing
|
|
77
|
+
if patch is not None:
|
|
78
|
+
data = _deep_merge(existing, patch)
|
|
79
|
+
|
|
80
|
+
# Non-blocking safety lints (warnings only — never refuse the save). They catch
|
|
81
|
+
# traps the server accepts silently: a phantom parentId, duplicate id/name
|
|
82
|
+
# configs, a multiple-select missing isList, and a patch key that isn't an
|
|
83
|
+
# existing Data field (the {"Data": {...}} wrapping mistake). See formlint.py.
|
|
84
|
+
lints = formlint.lint_form_data(data)
|
|
85
|
+
if patch is not None:
|
|
86
|
+
lints = formlint.lint_patch_keys(existing, patch) + lints
|
|
87
|
+
|
|
88
|
+
body = build_put_body(form, data=data, name=args.name, status=args.status, state=state,
|
|
89
|
+
is_private=is_private)
|
|
90
|
+
result = {
|
|
91
|
+
"id": form.get("id"),
|
|
92
|
+
"name": body["Name"],
|
|
93
|
+
"status": body["Status"],
|
|
94
|
+
"state": body["State"],
|
|
95
|
+
"isPrivate": body["IsPrivate"],
|
|
96
|
+
"patched_keys": sorted(patch) if patch else [],
|
|
97
|
+
"dry_run": bool(args.dry_run),
|
|
98
|
+
"applied": False,
|
|
99
|
+
}
|
|
100
|
+
if lints:
|
|
101
|
+
result["lints"] = lints
|
|
102
|
+
if args.dry_run:
|
|
103
|
+
result["dto"] = body
|
|
104
|
+
return result
|
|
105
|
+
guard = guard_unchanged(lambda: _fetch(client, args.id), form, force=args.force)
|
|
106
|
+
client.put("/api/FormTemplate", body)
|
|
107
|
+
result["applied"] = True
|
|
108
|
+
result["concurrency"] = guard
|
|
109
|
+
return result
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def form_add_element(client, args) -> dict:
|
|
113
|
+
raw = (Path(args.elements_file).read_text(encoding="utf-8") if args.elements_file
|
|
114
|
+
else args.elements)
|
|
115
|
+
if not raw:
|
|
116
|
+
raise UsageError("pass --elements '<json>' or --elements-file <path>")
|
|
117
|
+
try:
|
|
118
|
+
specs = json.loads(raw)
|
|
119
|
+
except json.JSONDecodeError as e:
|
|
120
|
+
raise UsageError(f"--elements must be valid JSON: {e}") from e
|
|
121
|
+
if isinstance(specs, dict):
|
|
122
|
+
specs = [specs]
|
|
123
|
+
if not isinstance(specs, list):
|
|
124
|
+
raise UsageError("--elements must be an element object or a list of them")
|
|
125
|
+
|
|
126
|
+
form = _fetch(client, args.id)
|
|
127
|
+
data = addelement.add_elements(form, specs, parent=args.parent)
|
|
128
|
+
|
|
129
|
+
lints = formlint.lint_form_data(data)
|
|
130
|
+
assignees, routing = reconcile_assignees(
|
|
131
|
+
form.get("assignees") or [], (form.get("data") or {}).get("elements") or [],
|
|
132
|
+
data.get("elements") or [])
|
|
133
|
+
body = build_put_body(form, data=data, assignees=assignees if routing else None)
|
|
134
|
+
added = [e for e in data["elements"] if e not in (form.get("data") or {}).get("elements", [])]
|
|
135
|
+
result = {
|
|
136
|
+
"id": form.get("id"), "name": body["Name"],
|
|
137
|
+
"added": [{"id": e["id"], "type": e.get("type"),
|
|
138
|
+
"name": addelement._name_of(e)} for e in added],
|
|
139
|
+
"element_count": len(data["elements"]),
|
|
140
|
+
"parent": args.parent,
|
|
141
|
+
"dry_run": bool(args.dry_run), "applied": False,
|
|
142
|
+
}
|
|
143
|
+
warning = addelement.unreachable_in_row(data["elements"], args.parent and
|
|
144
|
+
addelement._resolve_parent(data["elements"], args.parent))
|
|
145
|
+
if warning:
|
|
146
|
+
result["warning"] = warning
|
|
147
|
+
if routing:
|
|
148
|
+
result["assignees"] = routing
|
|
149
|
+
if lints:
|
|
150
|
+
result["lints"] = lints
|
|
151
|
+
if args.dry_run:
|
|
152
|
+
return result
|
|
153
|
+
guard = guard_unchanged(lambda: _fetch(client, args.id), form, force=args.force)
|
|
154
|
+
client.put("/api/FormTemplate", body)
|
|
155
|
+
result["applied"] = True
|
|
156
|
+
result["concurrency"] = guard
|
|
157
|
+
return result
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _add_element_args(p: argparse.ArgumentParser) -> None:
|
|
161
|
+
add_profile_arg(p)
|
|
162
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
163
|
+
p.add_argument("--elements", help="one authoring-config element object, or a JSON list of them")
|
|
164
|
+
p.add_argument("--elements-file", dest="elements_file",
|
|
165
|
+
help="path to a JSON file with the element(s)")
|
|
166
|
+
p.add_argument("--parent", help="place them inside this container, by element name or id")
|
|
167
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
168
|
+
help="build the new Data and report what would be added, without saving")
|
|
169
|
+
add_force_arg(p)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def form_delete_element(client, args) -> dict:
|
|
173
|
+
form = _fetch(client, args.id)
|
|
174
|
+
data, report = addelement.delete_element(form, args.element, force=bool(args.force_refs))
|
|
175
|
+
|
|
176
|
+
lints = formlint.lint_form_data(data)
|
|
177
|
+
assignees, routing = reconcile_assignees(
|
|
178
|
+
form.get("assignees") or [], (form.get("data") or {}).get("elements") or [],
|
|
179
|
+
data.get("elements") or [])
|
|
180
|
+
body = build_put_body(form, data=data, assignees=assignees if routing else None)
|
|
181
|
+
result = {"id": form.get("id"), "name": body["Name"], **report,
|
|
182
|
+
"dry_run": bool(args.dry_run), "applied": False}
|
|
183
|
+
if routing:
|
|
184
|
+
result["assignees"] = routing
|
|
185
|
+
if lints:
|
|
186
|
+
result["lints"] = lints
|
|
187
|
+
if args.dry_run:
|
|
188
|
+
return result
|
|
189
|
+
guard = guard_unchanged(lambda: _fetch(client, args.id), form, force=args.force)
|
|
190
|
+
client.put("/api/FormTemplate", body)
|
|
191
|
+
result["applied"] = True
|
|
192
|
+
result["concurrency"] = guard
|
|
193
|
+
return result
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _delete_element_args(p: argparse.ArgumentParser) -> None:
|
|
197
|
+
add_profile_arg(p)
|
|
198
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
199
|
+
p.add_argument("--element", required=True,
|
|
200
|
+
help="the control to remove, by its `name` config or its id")
|
|
201
|
+
p.add_argument("--force-refs", dest="force_refs", action="store_true",
|
|
202
|
+
help="delete even when the control is still referenced, or still contains "
|
|
203
|
+
"other controls, and report what that breaks")
|
|
204
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
205
|
+
help="report what would be removed, without saving")
|
|
206
|
+
add_force_arg(p)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _update_args(p: argparse.ArgumentParser) -> None:
|
|
210
|
+
add_profile_arg(p)
|
|
211
|
+
p.add_argument("--id", required=True, help="form template id")
|
|
212
|
+
p.add_argument("--data", help="JSON object deep-merged into the form's Data (a merge patch)")
|
|
213
|
+
p.add_argument("--data-file", dest="data_file",
|
|
214
|
+
help="path to a JSON file with the Data merge patch")
|
|
215
|
+
p.add_argument("--name", help="rename the form (top-level Name)")
|
|
216
|
+
p.add_argument("--status", type=int, choices=[0, 1],
|
|
217
|
+
help="publication status: 1=published, 0=draft")
|
|
218
|
+
p.add_argument("--state", choices=["true", "false"], help="enabled flag (true/false)")
|
|
219
|
+
p.add_argument("--is-private", dest="is_private", choices=["true", "false"],
|
|
220
|
+
help="reachability: false + --status 1 makes the form answer an anonymous "
|
|
221
|
+
"visitor on its custom URL; true keeps it behind a PROCESIO login")
|
|
222
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
223
|
+
help="build the PUT DTO and return it without saving (GET only)")
|
|
224
|
+
add_force_arg(p)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
ACTIONS = {
|
|
228
|
+
"form-add-element": ActionDef(
|
|
229
|
+
func=form_add_element,
|
|
230
|
+
add_args=_add_element_args,
|
|
231
|
+
needs_client=True,
|
|
232
|
+
description=(
|
|
233
|
+
"Add one or more controls to a LIVE form (authoring-config elements), splicing them "
|
|
234
|
+
"into Data.elements AND the data model without regenerating what is already there - "
|
|
235
|
+
"so every existing field path, and every process map that references one, survives. "
|
|
236
|
+
"--parent places them in a container by name or id; --dry-run previews. A new "
|
|
237
|
+
"control with an assignee or approver is routed: the form's top-level Assignees is "
|
|
238
|
+
"re-derived as the designer would, reported under `assignees`."
|
|
239
|
+
),
|
|
240
|
+
),
|
|
241
|
+
"form-delete-element": ActionDef(
|
|
242
|
+
func=form_delete_element,
|
|
243
|
+
add_args=_delete_element_args,
|
|
244
|
+
needs_client=True,
|
|
245
|
+
description=(
|
|
246
|
+
"Remove one control from a LIVE form: out of Data.elements, out of the form's data "
|
|
247
|
+
"model, and out of its container's own list - leaving every other element's id and "
|
|
248
|
+
"field path untouched, the same property that makes form-add-element safe. REFUSES "
|
|
249
|
+
"by default when the control still contains other controls or is still referenced "
|
|
250
|
+
"(an event, a RUN_PROCESS input/output map, a visibility condition), because a "
|
|
251
|
+
"dangling field path is saved without any error and the control that pointed at it "
|
|
252
|
+
"then silently launches nothing; --force-refs deletes anyway and reports what it "
|
|
253
|
+
"broke. References are found by element id, so one made by NAME is not detected. "
|
|
254
|
+
"Removing a control that routes a step (an approval control, an assigned section) "
|
|
255
|
+
"re-derives the form's top-level Assignees, reported under `assignees`. "
|
|
256
|
+
"--dry-run previews."
|
|
257
|
+
),
|
|
258
|
+
),
|
|
259
|
+
"form-update": ActionDef(
|
|
260
|
+
func=form_update,
|
|
261
|
+
add_args=_update_args,
|
|
262
|
+
needs_client=True,
|
|
263
|
+
description=(
|
|
264
|
+
"Safely save an arbitrary change to a LIVE form: GET it, deep-merge a --data "
|
|
265
|
+
"patch into its Data (and/or override --name/--status/--state/--is-private), then PUT the "
|
|
266
|
+
"server-accepted PascalCase DTO. Preserves elements/theme/code (never rebuilds "
|
|
267
|
+
"like form-edit). Last-write-wins guard (--force); --dry-run previews the DTO."
|
|
268
|
+
),
|
|
269
|
+
),
|
|
270
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Run a process THROUGH A FORM, the way a browser submission does.
|
|
2
|
+
|
|
3
|
+
Why this exists (and why it is not the same as `run-process-with-file`): a form and the
|
|
4
|
+
process behind it are assembled separately, and nothing in the process API asserts that the
|
|
5
|
+
two agree. A form whose submit button is wired to nothing, or whose input reaches the engine
|
|
6
|
+
but is never consumed, passes every process-side assertion ever written. Both defects have
|
|
7
|
+
shipped. Exercising the FORM surface is what catches them.
|
|
8
|
+
|
|
9
|
+
The FormProcess controller is the public front-end route (anonymous, scoped entirely by the
|
|
10
|
+
`formTemplateWorkspaceId` header). The sequence mirrors the process side:
|
|
11
|
+
|
|
12
|
+
publish (metadata only) -> upload each file (multipart) -> launch -> read variables
|
|
13
|
+
|
|
14
|
+
Two mechanics the generated `<method>-<path>` actions cannot reach, which is why this is a
|
|
15
|
+
curated handler: every call needs the `formTemplateWorkspaceId` header, and the file upload
|
|
16
|
+
is `multipart/form-data` with the field name `package`.
|
|
17
|
+
"""
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import json
|
|
22
|
+
import mimetypes
|
|
23
|
+
import os
|
|
24
|
+
import time
|
|
25
|
+
import uuid
|
|
26
|
+
|
|
27
|
+
from tools._lib.io import log
|
|
28
|
+
from tools.procesio.actiondef import ActionDef
|
|
29
|
+
from tools.procesio.client import parse_json_arg
|
|
30
|
+
from tools.procesio.errors import ProcesioAPIError, UsageError
|
|
31
|
+
from tools.procesio.handlers.common import add_profile_arg
|
|
32
|
+
|
|
33
|
+
_TERMINAL = {6, 40, 50}
|
|
34
|
+
_LABEL = {1: "starting", 6: "stopped", 40: "finished_with_errors", 50: "finished"}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _json_call(client, method, path, *, query=None, body=None, headers=None):
|
|
38
|
+
"""A JSON request that can carry extra headers. client.request() cannot, and these
|
|
39
|
+
endpoints are addressed by header, so everything here goes through request_bytes."""
|
|
40
|
+
status, raw, _ = client.request_bytes(method, path, query=query, body=body, headers=headers)
|
|
41
|
+
text = (raw or b"").decode("utf-8", "replace").strip()
|
|
42
|
+
parsed = None
|
|
43
|
+
if text:
|
|
44
|
+
try:
|
|
45
|
+
parsed = json.loads(text)
|
|
46
|
+
except ValueError:
|
|
47
|
+
parsed = text
|
|
48
|
+
if 200 <= status < 300:
|
|
49
|
+
return parsed
|
|
50
|
+
raise ProcesioAPIError(status, f"HTTP {status}",
|
|
51
|
+
parsed if isinstance(parsed, dict) else {"body": parsed})
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _instance_id(resp):
|
|
55
|
+
"""The published instance id, wherever this manager-defined shape puts it."""
|
|
56
|
+
if isinstance(resp, str) and resp.count("-") == 4:
|
|
57
|
+
return resp
|
|
58
|
+
if isinstance(resp, dict):
|
|
59
|
+
for k in ("id", "instanceId", "instanceID", "flowInstanceId"):
|
|
60
|
+
v = resp.get(k)
|
|
61
|
+
if isinstance(v, str) and v:
|
|
62
|
+
return v
|
|
63
|
+
flows = resp.get("flows")
|
|
64
|
+
if isinstance(flows, list) and flows and isinstance(flows[0], dict):
|
|
65
|
+
v = flows[0].get("id")
|
|
66
|
+
if v:
|
|
67
|
+
return v
|
|
68
|
+
for key in ("result", "value", "data", "instance"):
|
|
69
|
+
inner = resp.get(key)
|
|
70
|
+
if isinstance(inner, (dict, str)):
|
|
71
|
+
got = _instance_id(inner)
|
|
72
|
+
if got:
|
|
73
|
+
return got
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def run_form_with_files(client, args) -> dict:
|
|
78
|
+
form_id = args.form_id
|
|
79
|
+
process_id = args.process_id
|
|
80
|
+
ws = args.workspace_id or (client.profile or {}).get("workspace_id")
|
|
81
|
+
if not ws:
|
|
82
|
+
raise UsageError("--workspace-id is required: FormProcess is scoped by the "
|
|
83
|
+
"formTemplateWorkspaceId header")
|
|
84
|
+
hdr = {"formTemplateWorkspaceId": ws}
|
|
85
|
+
|
|
86
|
+
payload = parse_json_arg(args.payload, "--payload") if args.payload else {}
|
|
87
|
+
if not isinstance(payload, dict):
|
|
88
|
+
raise UsageError("--payload must be a JSON object")
|
|
89
|
+
|
|
90
|
+
# File inputs are staged as METADATA ONLY at publish; the bytes follow per file.
|
|
91
|
+
staged = []
|
|
92
|
+
for spec in (args.file or []):
|
|
93
|
+
if "=" not in spec:
|
|
94
|
+
raise UsageError(f"--file must be VARNAME=PATH, got {spec!r}")
|
|
95
|
+
var, path = spec.split("=", 1)
|
|
96
|
+
var, path = var.strip(), path.strip()
|
|
97
|
+
if not os.path.isfile(path):
|
|
98
|
+
raise UsageError(f"file not found for {var}: {path}")
|
|
99
|
+
size = os.path.getsize(path)
|
|
100
|
+
name = os.path.basename(path)
|
|
101
|
+
mime = mimetypes.guess_type(name)[0] or "application/octet-stream"
|
|
102
|
+
fid = str(uuid.uuid4())
|
|
103
|
+
staged.append({"var": var, "path": path, "name": name, "size": size,
|
|
104
|
+
"mime": mime, "file_id": fid})
|
|
105
|
+
payload[var] = {"path": "", "size": size, "mimeType": mime,
|
|
106
|
+
"name": name, "id": fid, "hash": ""}
|
|
107
|
+
|
|
108
|
+
log(f"publishing through form {form_id}")
|
|
109
|
+
pub = _json_call(client, "POST",
|
|
110
|
+
f"/api/FormProcess/{form_id}/{process_id}/publish",
|
|
111
|
+
body=payload, headers=hdr)
|
|
112
|
+
inst = _instance_id(pub)
|
|
113
|
+
if not inst:
|
|
114
|
+
raise ProcesioAPIError(0, "form publish returned no instance id",
|
|
115
|
+
{"response": pub})
|
|
116
|
+
log(f"instance {inst}")
|
|
117
|
+
|
|
118
|
+
for f in staged:
|
|
119
|
+
with open(f["path"], "rb") as fh:
|
|
120
|
+
content = fh.read()
|
|
121
|
+
client.request_multipart(
|
|
122
|
+
f"/api/FormProcess/{form_id}/{inst}/upload",
|
|
123
|
+
files={"package": (f["name"], content, f["mime"])},
|
|
124
|
+
headers={"flowTemplateId": process_id, "variableName": f["var"],
|
|
125
|
+
"fileId": f["file_id"], "formTemplateWorkspaceId": ws})
|
|
126
|
+
log(f"uploaded {f['name']} ({f['size']} bytes) -> {f['var']}")
|
|
127
|
+
|
|
128
|
+
# The launch route's second path segment is documented as processTemplateId, but the
|
|
129
|
+
# body already carries flowTemplateId, so on the process side that slot is the INSTANCE.
|
|
130
|
+
# Try the instance first and fall back, rather than guessing which the platform means.
|
|
131
|
+
body = {"connectionId": None, "flowTemplateId": process_id}
|
|
132
|
+
query = {"runSynchronous": "true" if args.synchronous else "false",
|
|
133
|
+
"secondsTimeOut": args.timeout}
|
|
134
|
+
launched, used = None, None
|
|
135
|
+
for seg in (inst, process_id):
|
|
136
|
+
try:
|
|
137
|
+
launched = _json_call(client, "POST",
|
|
138
|
+
f"/api/FormProcess/{form_id}/{seg}/launch",
|
|
139
|
+
query=query, body=body, headers=hdr)
|
|
140
|
+
used = seg
|
|
141
|
+
break
|
|
142
|
+
except ProcesioAPIError as e:
|
|
143
|
+
if seg == process_id:
|
|
144
|
+
raise
|
|
145
|
+
log(f"launch with instance in path failed ({e}); retrying with template")
|
|
146
|
+
log(f"launched (path segment used: {'instance' if used == inst else 'template'})")
|
|
147
|
+
|
|
148
|
+
variables, status = None, None
|
|
149
|
+
deadline = time.time() + max(int(args.timeout or 60), 5)
|
|
150
|
+
while time.time() < deadline:
|
|
151
|
+
try:
|
|
152
|
+
variables = _json_call(
|
|
153
|
+
client, "GET",
|
|
154
|
+
f"/api/FormProcess/{form_id}/{process_id}/{inst}/variables",
|
|
155
|
+
headers=hdr)
|
|
156
|
+
except ProcesioAPIError:
|
|
157
|
+
variables = None
|
|
158
|
+
status = None
|
|
159
|
+
if isinstance(variables, dict):
|
|
160
|
+
for k in ("status", "instanceStatus"):
|
|
161
|
+
if isinstance(variables.get(k), int):
|
|
162
|
+
status = variables[k]
|
|
163
|
+
inner = variables.get("instance")
|
|
164
|
+
if isinstance(inner, dict) and isinstance(inner.get("status"), int):
|
|
165
|
+
status = inner["status"]
|
|
166
|
+
if status in _TERMINAL or not args.synchronous:
|
|
167
|
+
break
|
|
168
|
+
time.sleep(3)
|
|
169
|
+
|
|
170
|
+
# The variables endpoint returns flow-variable DEFINITIONS and carries the runtime value
|
|
171
|
+
# in `defaultValue`, not `value`. Flatten to {name: value} so callers cannot misread an
|
|
172
|
+
# empty `value` key as "the form produced nothing" -- which is exactly the false negative
|
|
173
|
+
# this action exists to prevent.
|
|
174
|
+
flat = {}
|
|
175
|
+
if isinstance(variables, dict):
|
|
176
|
+
for item in (variables.get("variables") or []):
|
|
177
|
+
if isinstance(item, dict) and item.get("name"):
|
|
178
|
+
flat[item["name"]] = item.get("defaultValue")
|
|
179
|
+
|
|
180
|
+
return {"form_id": form_id, "process_id": process_id, "instance_id": inst,
|
|
181
|
+
"launch_path_segment": "instance" if used == inst else "template",
|
|
182
|
+
"files": [{"variable": f["var"], "name": f["name"], "size": f["size"]}
|
|
183
|
+
for f in staged],
|
|
184
|
+
"status": status, "status_label": _LABEL.get(status, str(status)),
|
|
185
|
+
"variable": flat, "variables": variables, "launch": launched}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _args(p: argparse.ArgumentParser) -> None:
|
|
189
|
+
add_profile_arg(p)
|
|
190
|
+
p.add_argument("--form-id", dest="form_id", required=True, help="form template id")
|
|
191
|
+
p.add_argument("--process-id", dest="process_id", required=True,
|
|
192
|
+
help="process (flow template) id the form submits to")
|
|
193
|
+
p.add_argument("--file", action="append",
|
|
194
|
+
help="VARNAME=PATH for a File input variable (repeatable)")
|
|
195
|
+
p.add_argument("--payload", help="non-file input variables as a JSON object")
|
|
196
|
+
p.add_argument("--synchronous", action="store_true", default=True,
|
|
197
|
+
help="wait for the flow to finish (default)")
|
|
198
|
+
p.add_argument("--no-synchronous", dest="synchronous", action="store_false",
|
|
199
|
+
help="fire and forget")
|
|
200
|
+
p.add_argument("--timeout", type=int, default=120,
|
|
201
|
+
help="synchronous wait, seconds (default 120)")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
ACTIONS = {
|
|
205
|
+
"run-form-with-files": ActionDef(
|
|
206
|
+
func=run_form_with_files, add_args=_args, needs_client=True,
|
|
207
|
+
description="Submit a form the way a browser does: publish -> upload files -> "
|
|
208
|
+
"launch -> read variables, through the public FormProcess endpoints. "
|
|
209
|
+
"Proves the form's own input/output maps carry values.",
|
|
210
|
+
),
|
|
211
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""Generic, full-coverage actions.
|
|
2
|
+
|
|
3
|
+
`request` reaches ANY of the ~247 documented Web-API endpoints, so the tool
|
|
4
|
+
covers the whole API surface even where there is no curated wrapper.
|
|
5
|
+
`list-endpoints` browses the bundled Swagger-derived index to discover paths.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
|
|
11
|
+
from tools.procesio import swagger
|
|
12
|
+
from tools.procesio.actiondef import ActionDef
|
|
13
|
+
from tools.procesio.client import parse_json_arg
|
|
14
|
+
from tools.procesio.errors import UsageError
|
|
15
|
+
from tools.procesio.handlers.common import add_profile_arg
|
|
16
|
+
from tools._lib.io import log
|
|
17
|
+
|
|
18
|
+
_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _unmangle_path(path: str) -> tuple[str, str | None]:
|
|
22
|
+
"""Recover a shell-mangled `--path` and return (clean_path, warning|None).
|
|
23
|
+
|
|
24
|
+
On Windows, Git Bash / MSYS rewrites a leading-slash argument the moment it
|
|
25
|
+
looks like a POSIX path: `--path /api/FormTemplate/{id}` reaches the tool as
|
|
26
|
+
`/C:/Program Files/Git/api/FormTemplate/{id}`, so the client builds
|
|
27
|
+
`…/C:/Program Files/Git/api/…` and the gateway answers 403 on the garbage
|
|
28
|
+
path. A real Web-API path starts with `/api/`, contains `/api/` exactly once,
|
|
29
|
+
and never contains a ':' — so when a ':' (a drive) shows up alongside an
|
|
30
|
+
`/api/`, the intended path is unambiguously the `/api/…` tail. We recover it
|
|
31
|
+
and warn (the fix is the caller's shell: pass `//api/…` or set
|
|
32
|
+
MSYS_NO_PATHCONV=1). Clean paths are returned untouched, so callers on
|
|
33
|
+
PowerShell/cmd are unaffected. A stray leading `//` (the `//api/…` MSYS
|
|
34
|
+
workaround) is also collapsed to a single slash.
|
|
35
|
+
"""
|
|
36
|
+
p = path
|
|
37
|
+
warn = None
|
|
38
|
+
low = p.lower()
|
|
39
|
+
if ":" in p and "/api/" in low:
|
|
40
|
+
tail = p[low.index("/api/"):]
|
|
41
|
+
warn = (f"--path looked shell-mangled ({path!r}); recovered {tail!r}. "
|
|
42
|
+
"Your shell (Git Bash/MSYS) rewrote the leading slash — pass "
|
|
43
|
+
"'//api/...' or set MSYS_NO_PATHCONV=1 to prevent this.")
|
|
44
|
+
p = tail
|
|
45
|
+
if p.startswith("//"):
|
|
46
|
+
p = p[1:]
|
|
47
|
+
return p, warn
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _request_args(p: argparse.ArgumentParser) -> None:
|
|
51
|
+
add_profile_arg(p)
|
|
52
|
+
p.add_argument("--method", default="GET",
|
|
53
|
+
help="HTTP method (GET/POST/PUT/PATCH/DELETE). Default GET.")
|
|
54
|
+
p.add_argument("--path", required=True,
|
|
55
|
+
help="endpoint path, e.g. /api/Projects or /api/Projects/{id}")
|
|
56
|
+
p.add_argument("--query", help="query params as a JSON object")
|
|
57
|
+
p.add_argument("--query-file", dest="query_file",
|
|
58
|
+
help="path to a UTF-8 JSON file for the query params "
|
|
59
|
+
"(use instead of --query to avoid shell JSON-quoting issues)")
|
|
60
|
+
p.add_argument("--body", help="request body as JSON (object or array)")
|
|
61
|
+
p.add_argument("--body-file", dest="body_file",
|
|
62
|
+
help="path to a UTF-8 JSON file for the request body "
|
|
63
|
+
"(use instead of --body for large payloads like full flow DTOs)")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def request(client, args) -> dict:
|
|
67
|
+
method = (args.method or "GET").upper()
|
|
68
|
+
if method not in _METHODS:
|
|
69
|
+
raise UsageError(f"--method must be one of {', '.join(_METHODS)}")
|
|
70
|
+
query_file = getattr(args, "query_file", None)
|
|
71
|
+
if query_file:
|
|
72
|
+
if args.query:
|
|
73
|
+
raise UsageError("pass either --query or --query-file, not both")
|
|
74
|
+
import json as _json
|
|
75
|
+
from pathlib import Path as _Path
|
|
76
|
+
try:
|
|
77
|
+
query = _json.loads(_Path(query_file).read_text(encoding="utf-8"))
|
|
78
|
+
except (OSError, ValueError) as e:
|
|
79
|
+
raise UsageError(f"--query-file could not be read as JSON: {e}") from e
|
|
80
|
+
else:
|
|
81
|
+
query = parse_json_arg(args.query, "query")
|
|
82
|
+
if query is not None and not isinstance(query, dict):
|
|
83
|
+
raise UsageError("--query must be a JSON object")
|
|
84
|
+
body_file = getattr(args, "body_file", None)
|
|
85
|
+
if body_file:
|
|
86
|
+
if args.body:
|
|
87
|
+
raise UsageError("pass either --body or --body-file, not both")
|
|
88
|
+
import json as _json
|
|
89
|
+
from pathlib import Path as _Path
|
|
90
|
+
try:
|
|
91
|
+
body = _json.loads(_Path(body_file).read_text(encoding="utf-8"))
|
|
92
|
+
except (OSError, ValueError) as e:
|
|
93
|
+
raise UsageError(f"--body-file could not be read as JSON: {e}") from e
|
|
94
|
+
else:
|
|
95
|
+
body = parse_json_arg(args.body, "body")
|
|
96
|
+
path, warn = _unmangle_path(args.path)
|
|
97
|
+
if warn:
|
|
98
|
+
log(warn)
|
|
99
|
+
result = client.request(method, path, query=query, body=body)
|
|
100
|
+
return {"method": method, "path": path, "result": result}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _list_args(p: argparse.ArgumentParser) -> None:
|
|
104
|
+
p.add_argument("--filter", help="substring match on path/tag/summary")
|
|
105
|
+
p.add_argument("--tag", help="exact tag filter, e.g. ProcessTemplate")
|
|
106
|
+
p.add_argument("--method", help="filter by HTTP method")
|
|
107
|
+
p.add_argument("--tags-only", action="store_true",
|
|
108
|
+
help="just list the available tags + counts")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def list_endpoints(args) -> dict:
|
|
112
|
+
if args.tags_only:
|
|
113
|
+
counts: dict[str, int] = {}
|
|
114
|
+
for e in swagger.all_endpoints():
|
|
115
|
+
counts[e["tag"]] = counts.get(e["tag"], 0) + 1
|
|
116
|
+
return {"meta": swagger.meta(),
|
|
117
|
+
"tags": [{"tag": t, "count": counts[t]} for t in sorted(counts)]}
|
|
118
|
+
found = swagger.find(args.filter, args.tag, args.method)
|
|
119
|
+
return {
|
|
120
|
+
"meta": swagger.meta(),
|
|
121
|
+
"count": len(found),
|
|
122
|
+
"endpoints": found,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
ACTIONS = {
|
|
127
|
+
"request": ActionDef(
|
|
128
|
+
func=request, add_args=_request_args, needs_client=True,
|
|
129
|
+
description="Call ANY Web-API endpoint: --method --path [--query JSON] [--body JSON].",
|
|
130
|
+
),
|
|
131
|
+
"list-endpoints": ActionDef(
|
|
132
|
+
func=list_endpoints, add_args=_list_args,
|
|
133
|
+
description="Browse the bundled Swagger index of all PROCESIO endpoints.",
|
|
134
|
+
),
|
|
135
|
+
}
|