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,354 @@
|
|
|
1
|
+
"""PROCESIO authentication: API-key headers and username/password cookie session.
|
|
2
|
+
|
|
3
|
+
Two auth modes, both validated live (2026-06-23) against the production Web API.
|
|
4
|
+
|
|
5
|
+
* **API key** (workspace-scoped): three request headers on every Web-API call -
|
|
6
|
+
`key` (key name), `value` (key value) and `workspaceid` (workspace GUID).
|
|
7
|
+
A master/personal key works without `workspaceid`; a scoped key requires it.
|
|
8
|
+
|
|
9
|
+
* **username/password** (full account): a **cookie session**, NOT a Bearer JWT.
|
|
10
|
+
Login is a form POST to `{web_base}/api/authentication`:
|
|
11
|
+
|
|
12
|
+
POST https://webapi.procesio.app/api/authentication
|
|
13
|
+
Content-Type: application/x-www-form-urlencoded
|
|
14
|
+
x-requested-by: playground-v1
|
|
15
|
+
body: username=<>&password=<>&client_id=procesio-ui
|
|
16
|
+
|
|
17
|
+
The 200 response is just {"message":"Authentication successful"} and sets two
|
|
18
|
+
HttpOnly cookies - `__Host-procesio.access` and `__Host-procesio.refresh` -
|
|
19
|
+
with the session expiry in the `x-session-expires-at` response header. Every
|
|
20
|
+
subsequent call carries those cookies plus the `x-requested-by` header. This
|
|
21
|
+
is exactly what the procesio.app SPA does (captured from a real login HAR);
|
|
22
|
+
the old auth.procesio.app / OAuth-grant flow in the docs is obsolete.
|
|
23
|
+
|
|
24
|
+
The HTTP `session` is always injected so tests never touch the network. It must
|
|
25
|
+
expose `.request(method, url, data=, json=, params=, headers=, timeout=) -> resp`
|
|
26
|
+
with `.status_code`, `.json()`, `.text`, `.headers`, and `.cookies`.
|
|
27
|
+
"""
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import time
|
|
31
|
+
from datetime import datetime
|
|
32
|
+
from typing import Any
|
|
33
|
+
|
|
34
|
+
from tools._lib.io import log
|
|
35
|
+
from tools.procesio import config, profiles
|
|
36
|
+
from tools.procesio.errors import AuthError, ProcesioAPIError
|
|
37
|
+
|
|
38
|
+
_BROWSER_UA = (
|
|
39
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
|
40
|
+
"(KHTML, like Gecko) Chrome/149.0 Safari/537.36"
|
|
41
|
+
)
|
|
42
|
+
LOGIN_PATH = "/api/authentication" # lowercase, form-encoded
|
|
43
|
+
# Renew a session from the refresh cookie WITHOUT re-sending the password. Same
|
|
44
|
+
# form-encoded shape as login; the 200 sets a fresh cookie pair. Verified live:
|
|
45
|
+
# the refreshed access cookie authenticates an ordinary Web-API call.
|
|
46
|
+
REFRESH_PATH = "/api/Authentication/refreshToken"
|
|
47
|
+
DEFAULT_REQUESTED_BY = "playground-v1" # the SPA's gateway identifier
|
|
48
|
+
ACCESS_COOKIE = "__Host-procesio.access"
|
|
49
|
+
REFRESH_COOKIE = "__Host-procesio.refresh"
|
|
50
|
+
_SKEW = 60 # treat a session as expired this many seconds early
|
|
51
|
+
# A token we just minted whose expiry we cannot read (not a JWT, no
|
|
52
|
+
# x-session-expires-at) is trusted for this long. A CACHED entry of unknown
|
|
53
|
+
# expiry is still distrusted — it could be arbitrarily old — but a token created
|
|
54
|
+
# one round-trip ago demonstrably is not, and re-logging in on the very next
|
|
55
|
+
# request instead is strictly worse. A rejected session still self-heals, because
|
|
56
|
+
# 401/403 triggers re-authentication anyway.
|
|
57
|
+
_ASSUMED_TTL = 300
|
|
58
|
+
|
|
59
|
+
# In-process cookie cache (name -> {"cookies": {...}, "expires_at": float|None}).
|
|
60
|
+
# Always works and avoids re-login within a single CLI invocation. The persistent
|
|
61
|
+
# cache is best-effort on top of this (see _persist_cookies).
|
|
62
|
+
_MEM_COOKIES: dict[str, dict] = {}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def requested_by(profile: dict) -> str:
|
|
66
|
+
return (profile or {}).get("requested_by") or DEFAULT_REQUESTED_BY
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _gateway_headers(profile: dict) -> dict[str, str]:
|
|
70
|
+
# Origin/Referer must match the environment's front-end host (CORS), which the
|
|
71
|
+
# client folds into the profile as app_base; defaults to production.
|
|
72
|
+
app = config.app_base(profile)
|
|
73
|
+
return {
|
|
74
|
+
"User-Agent": _BROWSER_UA,
|
|
75
|
+
"Accept": "application/json",
|
|
76
|
+
"x-requested-by": requested_by(profile),
|
|
77
|
+
"Origin": app,
|
|
78
|
+
"Referer": f"{app}/",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _parse_body(resp) -> Any:
|
|
83
|
+
try:
|
|
84
|
+
return resp.json()
|
|
85
|
+
except Exception: # noqa: BLE001
|
|
86
|
+
return {"raw_text": getattr(resp, "text", "")}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _trim(body: Any) -> Any:
|
|
90
|
+
if isinstance(body, dict):
|
|
91
|
+
return {k: v for k, v in body.items() if k != "raw_text"} or body
|
|
92
|
+
return body
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _cookies_from(resp) -> dict[str, str]:
|
|
96
|
+
"""Extract Set-Cookie name->value from a response, tolerant of a real
|
|
97
|
+
requests RequestsCookieJar or a plain dict (tests)."""
|
|
98
|
+
jar = getattr(resp, "cookies", None)
|
|
99
|
+
if not jar:
|
|
100
|
+
return {}
|
|
101
|
+
if isinstance(jar, dict):
|
|
102
|
+
return dict(jar)
|
|
103
|
+
try:
|
|
104
|
+
return dict(jar.get_dict())
|
|
105
|
+
except Exception: # noqa: BLE001
|
|
106
|
+
try:
|
|
107
|
+
return {c.name: c.value for c in jar}
|
|
108
|
+
except Exception: # noqa: BLE001
|
|
109
|
+
return {}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _parse_expiry(header_val) -> float | None:
|
|
113
|
+
"""`x-session-expires-at` may be epoch seconds/millis or an ISO-8601 string.
|
|
114
|
+
NOTE: this header carries the *refresh*-token expiry (~24h), NOT the access
|
|
115
|
+
cookie's. Prefer `_jwt_exp` of the access cookie for accurate freshness."""
|
|
116
|
+
if not header_val:
|
|
117
|
+
return None
|
|
118
|
+
s = str(header_val).strip()
|
|
119
|
+
try:
|
|
120
|
+
n = float(s)
|
|
121
|
+
return n / 1000.0 if n > 1e12 else n
|
|
122
|
+
except ValueError:
|
|
123
|
+
pass
|
|
124
|
+
try:
|
|
125
|
+
return datetime.fromisoformat(s.replace("Z", "+00:00")).timestamp()
|
|
126
|
+
except Exception: # noqa: BLE001
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _jwt_exp(token: str) -> float | None:
|
|
131
|
+
"""The `exp` claim (epoch seconds) of a JWT, or None. The access cookie is a
|
|
132
|
+
Bearer JWT (~30 min TTL); its own `exp` is the only accurate freshness signal
|
|
133
|
+
(the `x-session-expires-at` header reflects the longer-lived refresh token)."""
|
|
134
|
+
try:
|
|
135
|
+
import base64
|
|
136
|
+
import json as _json
|
|
137
|
+
parts = token.split(".")
|
|
138
|
+
if len(parts) != 3:
|
|
139
|
+
return None
|
|
140
|
+
pad = parts[1] + "=" * (-len(parts[1]) % 4)
|
|
141
|
+
claims = _json.loads(base64.urlsafe_b64decode(pad))
|
|
142
|
+
exp = claims.get("exp")
|
|
143
|
+
return float(exp) if exp is not None else None
|
|
144
|
+
except Exception: # noqa: BLE001
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _minted_expiry(cookies: dict, headers) -> float:
|
|
149
|
+
"""Expiry to record for a session we just obtained. Prefer the access
|
|
150
|
+
cookie's own `exp` (accurate, ~30 min), then the x-session-expires-at header,
|
|
151
|
+
then a short assumed TTL — never None, so a just-minted token is usable."""
|
|
152
|
+
return (_jwt_exp(cookies.get(ACCESS_COOKIE, ""))
|
|
153
|
+
or _parse_expiry((headers or {}).get("x-session-expires-at"))
|
|
154
|
+
or (time.time() + _ASSUMED_TTL))
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def login(profile: dict, session) -> dict:
|
|
158
|
+
"""Perform the cookie-session login. Returns
|
|
159
|
+
{"cookies": {name: value}, "expires_at": <epoch|None>}."""
|
|
160
|
+
username = profile.get("username")
|
|
161
|
+
password = profile.get("password")
|
|
162
|
+
if not username or not password:
|
|
163
|
+
raise AuthError("userpass profile is missing username/password")
|
|
164
|
+
headers = _gateway_headers(profile)
|
|
165
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
166
|
+
form = {"username": username, "password": password,
|
|
167
|
+
"client_id": config.client_id(profile)}
|
|
168
|
+
url = f"{config.web_base(profile)}{LOGIN_PATH}"
|
|
169
|
+
resp = session.request("POST", url, data=form, headers=headers, timeout=30)
|
|
170
|
+
status = getattr(resp, "status_code", 0)
|
|
171
|
+
if not (200 <= status < 300):
|
|
172
|
+
raise ProcesioAPIError(status or 0, "username/password login failed",
|
|
173
|
+
{"body": _trim(_parse_body(resp)), "url": url})
|
|
174
|
+
cookies = _cookies_from(resp)
|
|
175
|
+
if not cookies.get(ACCESS_COOKIE):
|
|
176
|
+
raise AuthError(
|
|
177
|
+
"login returned 2xx but no access cookie was set "
|
|
178
|
+
f"(cookies seen: {sorted(cookies)})"
|
|
179
|
+
)
|
|
180
|
+
resp_headers = getattr(resp, "headers", {}) or {}
|
|
181
|
+
return {"cookies": cookies,
|
|
182
|
+
"expires_at": _minted_expiry(cookies, resp_headers)}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def refresh(profile: dict, session, refresh_token: str) -> dict:
|
|
186
|
+
"""Renew the session from the refresh cookie — no password involved. Returns
|
|
187
|
+
the same shape as login(). Raises so the caller can fall back to a full login.
|
|
188
|
+
|
|
189
|
+
This is what the SPA gets for free (the gateway refreshes its cookies behind
|
|
190
|
+
a 307). A programmatic cookie client has to ask for it explicitly, which is
|
|
191
|
+
why the REFRESH cookie must be cached alongside the access one."""
|
|
192
|
+
headers = _gateway_headers(profile)
|
|
193
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
194
|
+
form = {"refresh_token": refresh_token, "client_id": config.client_id(profile)}
|
|
195
|
+
url = f"{config.web_base(profile)}{REFRESH_PATH}"
|
|
196
|
+
resp = session.request("POST", url, data=form, headers=headers, timeout=30)
|
|
197
|
+
status = getattr(resp, "status_code", 0)
|
|
198
|
+
if not (200 <= status < 300):
|
|
199
|
+
raise ProcesioAPIError(status or 0, "session refresh failed",
|
|
200
|
+
{"body": _trim(_parse_body(resp)), "url": url})
|
|
201
|
+
cookies = _cookies_from(resp)
|
|
202
|
+
if not cookies.get(ACCESS_COOKIE):
|
|
203
|
+
raise AuthError("refresh returned 2xx but set no access cookie "
|
|
204
|
+
f"(cookies seen: {sorted(cookies)})")
|
|
205
|
+
return {"cookies": cookies,
|
|
206
|
+
"expires_at": _minted_expiry(cookies, getattr(resp, "headers", {}))}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _usable_refresh_token(name: str, *entries) -> str | None:
|
|
210
|
+
"""The first REFRESH cookie still alive by its own `exp` — from the in-memory
|
|
211
|
+
entries first, then the persistent `refresh-<name>` credential. A dead refresh
|
|
212
|
+
token is worth nothing: fall straight through to a full login rather than
|
|
213
|
+
spending a round-trip proving it."""
|
|
214
|
+
now = time.time()
|
|
215
|
+
candidates = [((entry or {}).get("cookies") or {}).get(REFRESH_COOKIE)
|
|
216
|
+
for entry in entries]
|
|
217
|
+
try:
|
|
218
|
+
candidates.append(profiles.get_refresh_cookie(name))
|
|
219
|
+
except Exception: # noqa: BLE001 - a vault read must never break a request
|
|
220
|
+
pass
|
|
221
|
+
for tok in candidates:
|
|
222
|
+
if not tok:
|
|
223
|
+
continue
|
|
224
|
+
exp = _jwt_exp(tok)
|
|
225
|
+
if exp is None or exp - now > _SKEW:
|
|
226
|
+
return tok
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _is_fresh(entry: dict | None, now: float) -> bool:
|
|
231
|
+
if not entry or not entry.get("cookies", {}).get(ACCESS_COOKIE):
|
|
232
|
+
return False
|
|
233
|
+
exp = entry.get("expires_at")
|
|
234
|
+
# Unknown expiry -> do NOT trust it (re-login). The access cookie is a ~30 min
|
|
235
|
+
# JWT; a cached entry without an expiry could be long dead. force_login always
|
|
236
|
+
# records an accurate exp now, so this only bites legacy/None cache entries.
|
|
237
|
+
if exp is None:
|
|
238
|
+
return False
|
|
239
|
+
return exp - now > _SKEW
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _persist_cookies(name: str, token: dict) -> None:
|
|
243
|
+
"""Best-effort persistent cache, in TWO Credential Manager entries.
|
|
244
|
+
|
|
245
|
+
Both cookies must survive: the access cookie authenticates, and the REFRESH
|
|
246
|
+
cookie is what lets the next process renew the session without re-sending the
|
|
247
|
+
password (without it, every ~30 min of use costs a full login).
|
|
248
|
+
|
|
249
|
+
They cannot share one entry. Credential Manager caps a blob at 2560 BYTES and
|
|
250
|
+
keyring writes UTF-16LE, so the real ceiling is ~1280 CHARACTERS; the two JWTs
|
|
251
|
+
total ~1700 and are rejected together with WinError 1783 "stub received bad
|
|
252
|
+
data". Each alone fits, so they go to `token-<name>` and `refresh-<name>`.
|
|
253
|
+
Never raises: on failure we keep the in-process cache and re-login next time.
|
|
254
|
+
"""
|
|
255
|
+
cookies = token.get("cookies") or {}
|
|
256
|
+
slim = {"cookies": {ACCESS_COOKIE: cookies.get(ACCESS_COOKIE)},
|
|
257
|
+
"expires_at": token.get("expires_at")}
|
|
258
|
+
try:
|
|
259
|
+
profiles.set_token_cache(name, slim)
|
|
260
|
+
except Exception as e: # noqa: BLE001
|
|
261
|
+
log(f"[procesio] session not persisted to Credential Manager ({e}); "
|
|
262
|
+
f"using in-process cache (will re-login next invocation)")
|
|
263
|
+
refresh_cookie = cookies.get(REFRESH_COOKIE)
|
|
264
|
+
if not refresh_cookie:
|
|
265
|
+
return
|
|
266
|
+
try:
|
|
267
|
+
profiles.set_refresh_cookie(name, refresh_cookie)
|
|
268
|
+
except Exception as e: # noqa: BLE001
|
|
269
|
+
log(f"[procesio] refresh cookie not persisted ({e}); the next process "
|
|
270
|
+
f"will re-login with the password instead of refreshing")
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def force_login(name: str, profile: dict, session) -> dict:
|
|
274
|
+
"""Log in fresh and cache (memory + best-effort persistent). Returns the token."""
|
|
275
|
+
fresh = login(profile, session)
|
|
276
|
+
_MEM_COOKIES[name] = fresh
|
|
277
|
+
_persist_cookies(name, fresh)
|
|
278
|
+
return fresh
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def clear_cookies(name: str) -> None:
|
|
282
|
+
"""Drop both the in-process and persistent session for a profile."""
|
|
283
|
+
_MEM_COOKIES.pop(name, None)
|
|
284
|
+
profiles.clear_token_cache(name)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def try_refresh(name: str, profile: dict, session, *entries) -> dict | None:
|
|
288
|
+
"""Renew from a cached refresh cookie, or None if that is not possible.
|
|
289
|
+
Never raises — a failed refresh just means "do a full login"."""
|
|
290
|
+
token = _usable_refresh_token(name, *entries)
|
|
291
|
+
if not token:
|
|
292
|
+
return None
|
|
293
|
+
try:
|
|
294
|
+
fresh = refresh(profile, session, token)
|
|
295
|
+
except (AuthError, ProcesioAPIError) as e:
|
|
296
|
+
log(f"[procesio] session refresh failed ({e}); doing a full login")
|
|
297
|
+
return None
|
|
298
|
+
_MEM_COOKIES[name] = fresh
|
|
299
|
+
_persist_cookies(name, fresh)
|
|
300
|
+
return fresh
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def get_valid_cookies(name: str, profile: dict, session) -> dict[str, str]:
|
|
304
|
+
"""Return usable session cookies for a userpass profile. Order: in-process
|
|
305
|
+
cache → persistent cache → REFRESH → fresh login.
|
|
306
|
+
|
|
307
|
+
The refresh step matters: the access cookie is a ~30 min JWT, so without it
|
|
308
|
+
every half hour of use re-sends the username and password to the login
|
|
309
|
+
endpoint. Refreshing costs one round-trip and no credentials."""
|
|
310
|
+
now = time.time()
|
|
311
|
+
mem = _MEM_COOKIES.get(name)
|
|
312
|
+
if _is_fresh(mem, now):
|
|
313
|
+
return mem["cookies"]
|
|
314
|
+
cache = profiles.get_token_cache(name)
|
|
315
|
+
if _is_fresh(cache, now):
|
|
316
|
+
_MEM_COOKIES[name] = cache
|
|
317
|
+
return cache["cookies"]
|
|
318
|
+
renewed = try_refresh(name, profile, session, mem, cache)
|
|
319
|
+
if renewed is not None:
|
|
320
|
+
return renewed["cookies"]
|
|
321
|
+
return force_login(name, profile, session)["cookies"]
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def reauthenticate(name: str, profile: dict, session) -> dict[str, str]:
|
|
325
|
+
"""Recovery path after the gateway rejects our session mid-call. Try a
|
|
326
|
+
refresh first (cheap, no password); only if that fails drop the cached entry
|
|
327
|
+
and log in fully. Order matters — clearing the cache first would throw away
|
|
328
|
+
the very refresh cookie the refresh needs."""
|
|
329
|
+
mem = _MEM_COOKIES.get(name)
|
|
330
|
+
cache = profiles.get_token_cache(name)
|
|
331
|
+
renewed = try_refresh(name, profile, session, mem, cache)
|
|
332
|
+
if renewed is not None:
|
|
333
|
+
return renewed["cookies"]
|
|
334
|
+
clear_cookies(name)
|
|
335
|
+
return force_login(name, profile, session)["cookies"]
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def auth_headers(name: str, profile: dict, session) -> dict[str, str]:
|
|
339
|
+
"""Headers that authenticate a Web-API request for this profile."""
|
|
340
|
+
kind = profile.get("type")
|
|
341
|
+
if kind == "apikey":
|
|
342
|
+
key, value = profile.get("key"), profile.get("value")
|
|
343
|
+
if not key or not value:
|
|
344
|
+
raise AuthError("apikey profile is missing key/value")
|
|
345
|
+
headers = {"key": key, "value": value}
|
|
346
|
+
wsid = profile.get("workspace_id")
|
|
347
|
+
if wsid:
|
|
348
|
+
headers["workspaceid"] = wsid
|
|
349
|
+
return headers
|
|
350
|
+
if kind == "userpass":
|
|
351
|
+
cookies = get_valid_cookies(name, profile, session)
|
|
352
|
+
cookie_header = "; ".join(f"{k}={v}" for k, v in cookies.items())
|
|
353
|
+
return {"Cookie": cookie_header, "x-requested-by": requested_by(profile)}
|
|
354
|
+
raise AuthError(f"unknown profile type: {kind!r}")
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Spec-driven actions — one per PROCESIO Web-API endpoint (full 1:1 coverage).
|
|
2
|
+
|
|
3
|
+
Every operation in the bundled Swagger index (data/endpoints.json) becomes a
|
|
4
|
+
dispatchable action so the tool covers the *entire* API surface, not just the
|
|
5
|
+
curated shortcuts. Generation rules:
|
|
6
|
+
|
|
7
|
+
* **name** = `<method>-<path-slug>`, where the path is stripped of `/api/`,
|
|
8
|
+
`/` -> `-`, and `{param}` -> `by-param`. e.g.
|
|
9
|
+
GET /api/Projects/{id}/payload -> get-projects-by-id-payload
|
|
10
|
+
POST /api/Projects/instances/{id}/stop -> post-projects-instances-by-id-stop
|
|
11
|
+
Method-prefixing makes names unique (OpenAPI guarantees one op per
|
|
12
|
+
method+path) and predictable.
|
|
13
|
+
|
|
14
|
+
* **args**: `--profile` + one required `--<name>` per PATH param + one optional
|
|
15
|
+
`--<name>` per QUERY param + `--body` (JSON) when the operation takes a
|
|
16
|
+
request body + `--dry-run` (compose & return the request without sending).
|
|
17
|
+
|
|
18
|
+
Path params are taken from the `{...}` in the path itself; query params are the
|
|
19
|
+
rest of the recorded parameter list. Complex request bodies are passed through
|
|
20
|
+
as raw JSON for now; structured builders ("create a process/form/datatype/…")
|
|
21
|
+
will be layered on later as sub-tools without changing these endpoints.
|
|
22
|
+
|
|
23
|
+
The curated, ergonomically-named actions (list-processes, run-process, …) live
|
|
24
|
+
alongside these and take precedence on the (non-colliding) name space.
|
|
25
|
+
"""
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import re
|
|
29
|
+
|
|
30
|
+
from tools.procesio import swagger
|
|
31
|
+
from tools.procesio.actiondef import ActionDef
|
|
32
|
+
from tools.procesio.client import parse_json_arg
|
|
33
|
+
from tools.procesio.handlers.common import add_profile_arg
|
|
34
|
+
|
|
35
|
+
# Arg names the generator owns; a spec param must never collide with these.
|
|
36
|
+
_RESERVED_ARGS = {"profile", "body", "dry-run", "help"}
|
|
37
|
+
|
|
38
|
+
_PATH_PARAM = re.compile(r"\{([^}]+)\}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def action_name(method: str, path: str) -> str:
|
|
42
|
+
p = path[5:] if path.startswith("/api/") else path.lstrip("/")
|
|
43
|
+
segs = []
|
|
44
|
+
for seg in p.split("/"):
|
|
45
|
+
if not seg:
|
|
46
|
+
continue
|
|
47
|
+
m = _PATH_PARAM.fullmatch(seg)
|
|
48
|
+
segs.append(f"by-{m.group(1)}" if m else seg)
|
|
49
|
+
slug = "-".join(segs)
|
|
50
|
+
name = f"{method.lower()}-{slug}"
|
|
51
|
+
name = re.sub(r"[^a-zA-Z0-9-]", "-", name)
|
|
52
|
+
name = re.sub(r"-+", "-", name).strip("-").lower()
|
|
53
|
+
return name
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _path_params(path: str) -> list[str]:
|
|
57
|
+
return _PATH_PARAM.findall(path)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _make(method: str, path: str, path_params: list[str],
|
|
61
|
+
query_params: list[str], has_body: bool):
|
|
62
|
+
def add_args(p):
|
|
63
|
+
add_profile_arg(p)
|
|
64
|
+
for pp in path_params:
|
|
65
|
+
p.add_argument(f"--{pp}", required=True, help=f"path segment {{{pp}}}")
|
|
66
|
+
for qp in query_params:
|
|
67
|
+
p.add_argument(f"--{qp}", help="query parameter")
|
|
68
|
+
if has_body:
|
|
69
|
+
p.add_argument("--body", help="request body as JSON (object or array)")
|
|
70
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
71
|
+
help="compose and return the request without sending it")
|
|
72
|
+
|
|
73
|
+
def func(client, args):
|
|
74
|
+
resolved = path
|
|
75
|
+
for pp in path_params:
|
|
76
|
+
resolved = resolved.replace("{" + pp + "}", str(getattr(args, pp)))
|
|
77
|
+
query = {qp: getattr(args, qp) for qp in query_params}
|
|
78
|
+
query = {k: v for k, v in query.items() if v is not None}
|
|
79
|
+
body = parse_json_arg(getattr(args, "body", None), "body") if has_body else None
|
|
80
|
+
if getattr(args, "dry_run", False):
|
|
81
|
+
return {"dry_run": True, "method": method, "path": resolved,
|
|
82
|
+
"query": query, "body": body}
|
|
83
|
+
return {"result": client.request(method, resolved, query=query, body=body)}
|
|
84
|
+
|
|
85
|
+
return add_args, func
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _describe(ep: dict) -> str:
|
|
89
|
+
base = f"{ep['method']} {ep['path']} [{ep.get('tag', '')}]"
|
|
90
|
+
summary = (ep.get("summary") or "").strip()
|
|
91
|
+
if summary and summary.lower() not in base.lower():
|
|
92
|
+
base = f"{base} - {summary}"
|
|
93
|
+
return base[:240]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def build_actions(reserved: set[str] | None = None) -> dict[str, ActionDef]:
|
|
97
|
+
"""Build one ActionDef per endpoint. `reserved` names (curated/profile/auth)
|
|
98
|
+
are skipped so the curated actions win; method-prefixing means this never
|
|
99
|
+
actually drops an endpoint in practice."""
|
|
100
|
+
reserved = reserved or set()
|
|
101
|
+
out: dict[str, ActionDef] = {}
|
|
102
|
+
for ep in swagger.all_endpoints():
|
|
103
|
+
method, path = ep["method"], ep["path"]
|
|
104
|
+
pparams = _path_params(path)
|
|
105
|
+
qparams = [q for q in ep.get("params", [])
|
|
106
|
+
if q not in pparams and q not in _RESERVED_ARGS]
|
|
107
|
+
# A param colliding with a reserved arg name would break argparse; skip
|
|
108
|
+
# the body (rare) rather than crash, and note it in the description.
|
|
109
|
+
bad = [q for q in ep.get("params", []) if q in _RESERVED_ARGS]
|
|
110
|
+
has_body = bool(ep.get("body"))
|
|
111
|
+
name = action_name(method, path)
|
|
112
|
+
if name in reserved or name in out:
|
|
113
|
+
# extremely unlikely; disambiguate deterministically.
|
|
114
|
+
name = f"{name}-{method.lower()}"
|
|
115
|
+
add_args, func = _make(method, path, pparams, qparams, has_body)
|
|
116
|
+
desc = _describe(ep)
|
|
117
|
+
if bad:
|
|
118
|
+
desc += f" (note: spec params {bad} reachable via `request`)"
|
|
119
|
+
out[name] = ActionDef(func=func, add_args=add_args, needs_client=True,
|
|
120
|
+
description=desc)
|
|
121
|
+
return out
|