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,292 @@
|
|
|
1
|
+
"""Non-blocking safety lints for a form's Data DTO.
|
|
2
|
+
|
|
3
|
+
These encode form-build traps that the server ACCEPTS silently and that then cost
|
|
4
|
+
a debugging session to find (see PROCESIO-API-NOTES.md and FORM-DEV-GUIDE/08):
|
|
5
|
+
|
|
6
|
+
* **Phantom parentId** — an element whose `parentId` matches no element id renders
|
|
7
|
+
on NO pane. Tab/container membership is by `parentId` = a container element's id;
|
|
8
|
+
a dangling one is invisible, not an error (O6).
|
|
9
|
+
* **Duplicate id/name configs** — two elements sharing the designer `id` or `name`
|
|
10
|
+
config collide for selectors and process mapping.
|
|
11
|
+
* **Patch wrapping mistake** — a form-update `--data` patch whose top-level key is
|
|
12
|
+
not an existing Data field is merged in as an inert junk key; the classic case is
|
|
13
|
+
wrapping the patch as `{"Data": {...}}` (O7).
|
|
14
|
+
* **Multiple-select without isList** — a select with `multiple=true` whose `value`
|
|
15
|
+
config is not marked `isList` maps a list into a scalar.
|
|
16
|
+
* **IS_TRUE / IS_FALSE on a Boolean variable whose default is the text "false"** — the
|
|
17
|
+
designer stores a Boolean form variable's default as a STRING ("False" / "false"), and a
|
|
18
|
+
condition treats any non-empty string as true. Measured live: default "false" or "False"
|
|
19
|
+
→ IS_TRUE passes and IS_FALSE fails; default null → IS_TRUE fails and IS_FALSE passes.
|
|
20
|
+
A gate like `isConfirmed IS_TRUE` on such a default is always open.
|
|
21
|
+
* **Field names a designer save renames** — a form built through the API keeps its field
|
|
22
|
+
names as written, but one save in the designer re-keys `ProcesioForm.data.fields`: it
|
|
23
|
+
splits each name on underscores, lowercases the parts and joins them in camelCase
|
|
24
|
+
(`orderList` -> `orderlist`, `order_id` -> `orderId`; measured on two names, hyphens and
|
|
25
|
+
spaces not tested). Form JS reading the original name then gets `undefined`. Only a
|
|
26
|
+
single lowercase word survives unchanged. One warning per form, naming them all.
|
|
27
|
+
That re-key happens only to a form whose `dataModelAttributeFormatVersion` is not "1": the
|
|
28
|
+
designer reads a missing version as the legacy "0" format (user-playground
|
|
29
|
+
Builder.component.vue; Form.model.ts::generateFormDataModel lower-cases under "0" and keeps
|
|
30
|
+
the name under "1"). A form at "1" keeps its names through a designer save (measured
|
|
31
|
+
2026-09-25 and 2026-10-05), so it draws no warning; form-create writes "1" since 2026-10-05.
|
|
32
|
+
|
|
33
|
+
Pure and side-effect-free: each returns a list of human-readable warning strings.
|
|
34
|
+
Warnings, never blockers — the caller attaches them to its result JSON.
|
|
35
|
+
"""
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
import re
|
|
39
|
+
from typing import Any
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _elements(data: Any) -> list:
|
|
43
|
+
if isinstance(data, dict):
|
|
44
|
+
els = data.get("elements")
|
|
45
|
+
if isinstance(els, list):
|
|
46
|
+
return els
|
|
47
|
+
return []
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _cfg_value(element: dict, key: str):
|
|
51
|
+
for c in element.get("configs") or []:
|
|
52
|
+
if isinstance(c, dict) and c.get("key") == key:
|
|
53
|
+
return c.get("value")
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _cfg(element: dict, key: str):
|
|
58
|
+
for c in element.get("configs") or []:
|
|
59
|
+
if isinstance(c, dict) and c.get("key") == key:
|
|
60
|
+
return c
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _label(element: dict) -> str:
|
|
65
|
+
"""Best identifier for a message: the designer name, else the element id."""
|
|
66
|
+
name = _cfg_value(element, "name")
|
|
67
|
+
if isinstance(name, str) and name.strip():
|
|
68
|
+
return f"{name.strip()!r}"
|
|
69
|
+
return f"id {element.get('id')!r}"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def lint_phantom_parent(data: Any) -> list[str]:
|
|
73
|
+
els = _elements(data)
|
|
74
|
+
ids = {e.get("id") for e in els if isinstance(e, dict)}
|
|
75
|
+
out = []
|
|
76
|
+
for e in els:
|
|
77
|
+
if not isinstance(e, dict):
|
|
78
|
+
continue
|
|
79
|
+
pid = e.get("parentId")
|
|
80
|
+
if pid not in (None, "") and pid not in ids:
|
|
81
|
+
out.append(
|
|
82
|
+
f"element {_label(e)} has parentId {pid!r} matching no element on the "
|
|
83
|
+
f"form — it renders on NO pane (dangling container reference). Point it "
|
|
84
|
+
f"at a real container/tab element id, or set parentId to null for a "
|
|
85
|
+
f"top-level element.")
|
|
86
|
+
return out
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def lint_duplicate_configs(data: Any) -> list[str]:
|
|
90
|
+
els = _elements(data)
|
|
91
|
+
out = []
|
|
92
|
+
for cfg_key in ("id", "name"):
|
|
93
|
+
seen: dict[str, int] = {}
|
|
94
|
+
for e in els:
|
|
95
|
+
if not isinstance(e, dict):
|
|
96
|
+
continue
|
|
97
|
+
val = _cfg_value(e, cfg_key)
|
|
98
|
+
if isinstance(val, str) and val.strip():
|
|
99
|
+
seen[val.strip()] = seen.get(val.strip(), 0) + 1
|
|
100
|
+
for val, n in seen.items():
|
|
101
|
+
if n > 1:
|
|
102
|
+
out.append(
|
|
103
|
+
f"{n} elements share the same {cfg_key} config {val!r}; a duplicate "
|
|
104
|
+
f"{cfg_key} collides for CSS/JS selectors and process mapping — make "
|
|
105
|
+
f"each element's {cfg_key} unique.")
|
|
106
|
+
return out
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def lint_multiple_select_islist(data: Any) -> list[str]:
|
|
110
|
+
els = _elements(data)
|
|
111
|
+
out = []
|
|
112
|
+
for e in els:
|
|
113
|
+
if not isinstance(e, dict):
|
|
114
|
+
continue
|
|
115
|
+
multiple = _cfg_value(e, "multiple")
|
|
116
|
+
if multiple is True or (isinstance(multiple, str) and multiple.lower() == "true"):
|
|
117
|
+
value_cfg = _cfg(e, "value") or {}
|
|
118
|
+
is_list = value_cfg.get("isList") if isinstance(value_cfg, dict) else None
|
|
119
|
+
if not is_list:
|
|
120
|
+
out.append(
|
|
121
|
+
f"element {_label(e)} is a multiple-select (multiple=true) but its "
|
|
122
|
+
f"value config is not marked isList — a multi-value selection maps "
|
|
123
|
+
f"into a scalar. Set isList on the value config / the mapped "
|
|
124
|
+
f"data-model attribute.")
|
|
125
|
+
return out
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def lint_patch_keys(existing_data: Any, patch: Any) -> list[str]:
|
|
129
|
+
"""A form-update --data patch whose top-level key is not an existing Data field
|
|
130
|
+
is added as a (probably inert) junk key. Flags the classic `{"Data": {...}}`
|
|
131
|
+
wrapping mistake explicitly."""
|
|
132
|
+
if not isinstance(patch, dict) or not isinstance(existing_data, dict):
|
|
133
|
+
return []
|
|
134
|
+
known = set(existing_data.keys())
|
|
135
|
+
out = []
|
|
136
|
+
for k in patch:
|
|
137
|
+
if k in known:
|
|
138
|
+
continue
|
|
139
|
+
if k.lower() == "data":
|
|
140
|
+
out.append(
|
|
141
|
+
f"patch top-level key {k!r} is not a Data field — this is almost "
|
|
142
|
+
f"certainly the wrapping mistake: pass the INNER fields directly (e.g. "
|
|
143
|
+
f'--data \'{{"hideBranding": true}}\'), not wrapped as {{{k!r}: {{...}}}}. '
|
|
144
|
+
f"As written it creates an inert junk key that changes nothing.")
|
|
145
|
+
else:
|
|
146
|
+
sample = ", ".join(sorted(known)[:8]) or "(none)"
|
|
147
|
+
out.append(
|
|
148
|
+
f"patch top-level key {k!r} is not an existing Data field — it will be "
|
|
149
|
+
f"ADDED as a new key (no existing value is changed). Existing fields "
|
|
150
|
+
f"include: {sample}. Check for a typo/casing mismatch.")
|
|
151
|
+
return out
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
_BOOLEAN_TESTS = ("IS_TRUE", "IS_FALSE")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def string_boolean_conditions(events: Any, variables: Any, where: str) -> list[str]:
|
|
158
|
+
"""Warnings for IS_TRUE / IS_FALSE conditions, in `events`, on a form variable whose
|
|
159
|
+
default is the TEXT "false" (any case): the condition reads it as true. Shared by the
|
|
160
|
+
whole-form lint and by form-set-element-chains, which checks only the chains it writes.
|
|
161
|
+
A "true" text default is left alone - it evaluates the way it reads."""
|
|
162
|
+
defaults = {v.get("id"): v for v in variables or [] if isinstance(v, dict)}
|
|
163
|
+
out = []
|
|
164
|
+
for ev in events or []:
|
|
165
|
+
conds = ((ev or {}).get("config") or {}).get("conditions") or []
|
|
166
|
+
for c in conds:
|
|
167
|
+
op = str(c.get("operator") or "")
|
|
168
|
+
var = defaults.get((c.get("leftOperator") or {}).get("value"))
|
|
169
|
+
if op not in _BOOLEAN_TESTS or var is None:
|
|
170
|
+
continue
|
|
171
|
+
default = var.get("defaultValue")
|
|
172
|
+
if not (isinstance(default, str) and default.strip().lower() == "false"):
|
|
173
|
+
continue
|
|
174
|
+
effect = ("PASSES although it reads false" if op == "IS_TRUE"
|
|
175
|
+
else "never passes although it reads false")
|
|
176
|
+
out.append(
|
|
177
|
+
f"{where}: condition `{var.get('name')} {op}` reads a form variable whose "
|
|
178
|
+
f"default is the TEXT {default!r}; a condition treats any non-empty text as "
|
|
179
|
+
f"true, so {op} {effect}, until something writes a real boolean (measured "
|
|
180
|
+
f"live). Set the default to null, or branch with EQUALS on a value that really "
|
|
181
|
+
f"is text (a select's value, or a field your own flow writes).")
|
|
182
|
+
return out
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def lint_string_boolean_conditions(data: Any) -> list[str]:
|
|
186
|
+
if not isinstance(data, dict):
|
|
187
|
+
return []
|
|
188
|
+
variables = data.get("variables") or []
|
|
189
|
+
out = string_boolean_conditions(data.get("events") or [], variables, "form-level event")
|
|
190
|
+
for e in _elements(data):
|
|
191
|
+
if not isinstance(e, dict):
|
|
192
|
+
continue
|
|
193
|
+
for c in e.get("configs") or []:
|
|
194
|
+
if (isinstance(c, dict) and str(c.get("key", "")).startswith("on")
|
|
195
|
+
and isinstance(c.get("value"), dict)):
|
|
196
|
+
out += string_boolean_conditions(c["value"].get("events"), variables,
|
|
197
|
+
f"element {_label(e)} {c.get('key')}")
|
|
198
|
+
return out
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
_SINGLE_WORD = re.compile(r"[a-z0-9]+")
|
|
202
|
+
_UNDERSCORED = re.compile(r"[A-Za-z0-9_]+")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def designer_key(name: str) -> str | None:
|
|
206
|
+
"""The key a designer save gives a field name, or None where that rule was not
|
|
207
|
+
measured (a name with hyphens, spaces or other characters)."""
|
|
208
|
+
if not _UNDERSCORED.fullmatch(name or ""):
|
|
209
|
+
return None
|
|
210
|
+
parts = [p.lower() for p in name.split("_") if p]
|
|
211
|
+
if not parts:
|
|
212
|
+
return None
|
|
213
|
+
return parts[0] + "".join(p[:1].upper() + p[1:] for p in parts[1:])
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def lint_field_names(data: Any) -> list[str]:
|
|
217
|
+
"""One warning naming every element whose name a designer save would re-key.
|
|
218
|
+
|
|
219
|
+
None for a form at dataModelAttributeFormatVersion "1": the designer keeps its names."""
|
|
220
|
+
if isinstance(data, dict) and str(data.get("dataModelAttributeFormatVersion") or "") == "1":
|
|
221
|
+
return []
|
|
222
|
+
renamed = []
|
|
223
|
+
for el in _elements(data):
|
|
224
|
+
name = _cfg_value(el, "name")
|
|
225
|
+
if not isinstance(name, str) or not name or _SINGLE_WORD.fullmatch(name):
|
|
226
|
+
continue
|
|
227
|
+
key = designer_key(name)
|
|
228
|
+
renamed.append(f"{name} -> {key}" if key else f"{name} -> (renamed; rule not measured)")
|
|
229
|
+
if not renamed:
|
|
230
|
+
return []
|
|
231
|
+
shown = ", ".join(renamed[:8])
|
|
232
|
+
if len(renamed) > 8:
|
|
233
|
+
shown += f", and {len(renamed) - 8} more"
|
|
234
|
+
return [f"{len(renamed)} field name(s) are not a single lowercase word, and a save in the "
|
|
235
|
+
f"designer re-keys them in ProcesioForm.data.fields: {shown}. Form JS that reads "
|
|
236
|
+
f"the original name then gets undefined. Read fields through a lookup that ignores "
|
|
237
|
+
f"case and underscores, or name them as single lowercase words "
|
|
238
|
+
f"(FORM-DEV-GUIDE/08-PITFALLS.md)."]
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# Form custom CSS is scoped to the form container: every selector's last compound gets
|
|
242
|
+
# `:where([data-form-css-scope=<id>], [data-form-css-scope=<id>] *)` appended. UI the JS mounts
|
|
243
|
+
# on document.body, and `:root` / `html` / `body` rules, sit outside that scope and get no style
|
|
244
|
+
# unless the JS copies the attribute onto <html>. See FORM-DEV-GUIDE/02-CODE-INJECTION.md §2.
|
|
245
|
+
_SCOPE_ATTR = "data-form-css-scope"
|
|
246
|
+
_BODY_MOUNT = re.compile(
|
|
247
|
+
r"document\.body\s*\.\s*(?:appendChild|append|prepend|insertBefore|insertAdjacentHTML|"
|
|
248
|
+
r"insertAdjacentElement|replaceChildren)\b"
|
|
249
|
+
r"|document\.body\s*\.\s*innerHTML\s*\+?="
|
|
250
|
+
r"|\.mount\(\s*(?:document\.body\b|['\"]body['\"])")
|
|
251
|
+
_CSS_COMMENT = re.compile(r"/\*.*?\*/", re.S)
|
|
252
|
+
_CSS_PRELUDE = re.compile(r"([^{}]+)\{")
|
|
253
|
+
_PAGE_SELECTOR = re.compile(r"(:root|html|body)(?![\w-])", re.I)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def lint_form_code_scope(css: str | None, js: str | None) -> list[str]:
|
|
257
|
+
"""One warning when the form code relies on styling outside the form's CSS scope.
|
|
258
|
+
|
|
259
|
+
Fires when the JS mounts UI on document.body, or the CSS styles :root / html / body, and the
|
|
260
|
+
JS never mentions the scope attribute (the known fix copies it onto <html>). A form whose UI
|
|
261
|
+
stays inside the form container triggers neither and gets no warning."""
|
|
262
|
+
css, js = css or "", js or ""
|
|
263
|
+
if _SCOPE_ATTR in js:
|
|
264
|
+
return []
|
|
265
|
+
reasons = []
|
|
266
|
+
if _BODY_MOUNT.search(js):
|
|
267
|
+
reasons.append("the JS renders UI onto document.body")
|
|
268
|
+
heads = set()
|
|
269
|
+
for prelude in _CSS_PRELUDE.findall(_CSS_COMMENT.sub("", css)):
|
|
270
|
+
prelude = prelude.strip()
|
|
271
|
+
if prelude.startswith("@"):
|
|
272
|
+
continue
|
|
273
|
+
for sel in prelude.split(","):
|
|
274
|
+
m = _PAGE_SELECTOR.match(sel.strip())
|
|
275
|
+
if m:
|
|
276
|
+
heads.add(m.group(1).lower())
|
|
277
|
+
if heads:
|
|
278
|
+
reasons.append("the CSS styles " + " / ".join(sorted(heads)))
|
|
279
|
+
if not reasons:
|
|
280
|
+
return []
|
|
281
|
+
return [f"form code: {' and '.join(reasons)}, but the form's custom CSS is scoped to the form "
|
|
282
|
+
f"container ([{_SCOPE_ATTR}]), so those styles will not apply. Before mounting, copy the "
|
|
283
|
+
f"container's {_SCOPE_ATTR} value onto <html> (FORM-DEV-GUIDE/02-CODE-INJECTION.md §2)."]
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def lint_form_data(data: Any) -> list[str]:
|
|
287
|
+
"""All structural (element-level) lints for a form's Data."""
|
|
288
|
+
return (lint_phantom_parent(data)
|
|
289
|
+
+ lint_duplicate_configs(data)
|
|
290
|
+
+ lint_multiple_select_islist(data)
|
|
291
|
+
+ lint_string_boolean_conditions(data)
|
|
292
|
+
+ lint_field_names(data))
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Regenerate tool.yaml's `actions:` block from the live dispatcher.
|
|
2
|
+
|
|
3
|
+
The manifest is the source of truth (CLAUDE.md Hard rule 3) and the sync guard
|
|
4
|
+
(tests/test_manifest_sync.py) demands it match the dispatcher's actions/args
|
|
5
|
+
EXACTLY. With 250+ actions the file is ~200 KB — far too large to hand-edit,
|
|
6
|
+
especially under the Cowork mount's ~15 KB Write/Edit cap. So this script is the
|
|
7
|
+
ONLY supported way to change the action surface:
|
|
8
|
+
|
|
9
|
+
1. change handlers / autogen / dto actions,
|
|
10
|
+
2. run `python -m tools.procesio.gen_manifest` (writes tool.yaml directly via
|
|
11
|
+
Python — not the capped Write tool),
|
|
12
|
+
3. `pytest tools/procesio/tests/test_manifest_sync.py` stays green.
|
|
13
|
+
|
|
14
|
+
It preserves the hand-written header (everything up to and including the
|
|
15
|
+
`actions:` line — name/description/version/routing/secrets + comments) verbatim,
|
|
16
|
+
and regenerates only the actions list, sorted by name for a stable diff. Arg
|
|
17
|
+
type/required/description are introspected from each action's argparse exactly as
|
|
18
|
+
the sync test reads them, so the two can never drift.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
import yaml
|
|
26
|
+
|
|
27
|
+
TOOL_ROOT = Path(__file__).resolve().parent
|
|
28
|
+
MANIFEST = TOOL_ROOT / "tool.yaml"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _arg_type(action: argparse.Action) -> str:
|
|
32
|
+
if isinstance(action, (argparse._StoreTrueAction, argparse._StoreFalseAction)):
|
|
33
|
+
return "boolean"
|
|
34
|
+
if action.type is int:
|
|
35
|
+
return "integer"
|
|
36
|
+
if action.type is float:
|
|
37
|
+
return "number"
|
|
38
|
+
return "string"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _action_args(defn) -> list[dict]:
|
|
42
|
+
"""The arg specs for one ActionDef, in argparse declaration order — the exact
|
|
43
|
+
surface the sync test compares against."""
|
|
44
|
+
parser = argparse.ArgumentParser()
|
|
45
|
+
defn.add_args(parser)
|
|
46
|
+
out: list[dict] = []
|
|
47
|
+
for action in parser._actions:
|
|
48
|
+
names = [o for o in action.option_strings if o.startswith("--") and o != "--help"]
|
|
49
|
+
if not names:
|
|
50
|
+
continue
|
|
51
|
+
name = names[0][2:]
|
|
52
|
+
spec = {
|
|
53
|
+
"name": name,
|
|
54
|
+
"type": _arg_type(action),
|
|
55
|
+
"required": bool(getattr(action, "required", False)),
|
|
56
|
+
"description": (action.help or "").strip(),
|
|
57
|
+
}
|
|
58
|
+
# A structured argument publishes its schema too: `help=` can say an arg takes
|
|
59
|
+
# JSON, never what belongs in it, so without this a manifest reader has to
|
|
60
|
+
# discover the shape from validation errors one layer at a time.
|
|
61
|
+
schema = (getattr(defn, "arg_schemas", None) or {}).get(name)
|
|
62
|
+
if schema:
|
|
63
|
+
spec["schema"] = schema
|
|
64
|
+
out.append(spec)
|
|
65
|
+
return out
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def build_actions_block() -> list[dict]:
|
|
69
|
+
from tools.procesio import main
|
|
70
|
+
actions = []
|
|
71
|
+
for name in sorted(main.ACTIONS):
|
|
72
|
+
defn = main.ACTIONS[name]
|
|
73
|
+
entry = {
|
|
74
|
+
"name": name,
|
|
75
|
+
"description": (defn.description or "").strip(),
|
|
76
|
+
"args": _action_args(defn),
|
|
77
|
+
}
|
|
78
|
+
examples = getattr(defn, "examples", None)
|
|
79
|
+
if examples:
|
|
80
|
+
entry["examples"] = examples
|
|
81
|
+
actions.append(entry)
|
|
82
|
+
return actions
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _header_text() -> str:
|
|
86
|
+
"""Everything up to and including the `actions:` line, preserved verbatim so
|
|
87
|
+
hand-written comments / routing / secrets / the long description are kept."""
|
|
88
|
+
text = MANIFEST.read_text(encoding="utf-8")
|
|
89
|
+
lines = text.splitlines(keepends=True)
|
|
90
|
+
for i, line in enumerate(lines):
|
|
91
|
+
if line.rstrip("\n") == "actions:":
|
|
92
|
+
return "".join(lines[: i + 1])
|
|
93
|
+
raise SystemExit("tool.yaml has no top-level `actions:` line to anchor on")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def render() -> str:
|
|
97
|
+
header = _header_text()
|
|
98
|
+
body = yaml.safe_dump(
|
|
99
|
+
build_actions_block(),
|
|
100
|
+
sort_keys=False, default_flow_style=False, allow_unicode=True,
|
|
101
|
+
width=10_000, # never wrap a description onto a second line
|
|
102
|
+
)
|
|
103
|
+
return header + body
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def main() -> int:
|
|
107
|
+
new_text = render()
|
|
108
|
+
# newline="\n" is load-bearing: the repo stores this manifest with LF, and a
|
|
109
|
+
# default Windows write turns every one of its ~9,000 lines into a diff hunk, which
|
|
110
|
+
# buries the handful that actually changed and makes the manifest unreviewable.
|
|
111
|
+
MANIFEST.write_text(new_text, encoding="utf-8", newline="\n") # direct write (not capped)
|
|
112
|
+
n_actions = new_text.count("\n- name:")
|
|
113
|
+
print(f"wrote {MANIFEST} ({len(new_text)} bytes, {n_actions} actions)")
|
|
114
|
+
return 0
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""PROCESIO action handlers."""
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Auth lifecycle actions: login, check-auth, logout.
|
|
2
|
+
|
|
3
|
+
These are client-backed (they need a profile + session) but deliberately never
|
|
4
|
+
return a token value - only whether authentication works and how it was done.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from tools.procesio import auth, config, profiles
|
|
9
|
+
from tools.procesio.actiondef import ActionDef
|
|
10
|
+
from tools.procesio.errors import ProcesioAPIError
|
|
11
|
+
from tools.procesio.handlers.common import add_profile_arg
|
|
12
|
+
|
|
13
|
+
# A cheap, side-effect-free GET used to confirm a credential actually works.
|
|
14
|
+
# /api/Workspaces lists the caller's workspaces; it requires only valid auth.
|
|
15
|
+
_PROBE_PATH = "/api/Workspaces"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def login(client, _args) -> dict:
|
|
19
|
+
"""Force-acquire (userpass) or confirm (apikey) authentication."""
|
|
20
|
+
kind = client.profile.get("type")
|
|
21
|
+
if kind == "userpass":
|
|
22
|
+
session = auth.force_login(client.name, client.profile, client._session)
|
|
23
|
+
cookies = session.get("cookies", {})
|
|
24
|
+
return {
|
|
25
|
+
"authenticated": True,
|
|
26
|
+
"mode": "userpass",
|
|
27
|
+
"profile": client.name,
|
|
28
|
+
"environment": client.env.get("name"),
|
|
29
|
+
"session_cached": True,
|
|
30
|
+
"cookie_names": sorted(cookies.keys()), # names only, never values
|
|
31
|
+
"expires_at": session.get("expires_at"),
|
|
32
|
+
"web_base": config.web_base(client.profile),
|
|
33
|
+
"login_path": auth.LOGIN_PATH,
|
|
34
|
+
}
|
|
35
|
+
# apikey: nothing to fetch - just confirm the headers are well-formed.
|
|
36
|
+
headers = auth.auth_headers(client.name, client.profile, client._session)
|
|
37
|
+
return {
|
|
38
|
+
"authenticated": True,
|
|
39
|
+
"mode": "apikey",
|
|
40
|
+
"profile": client.name,
|
|
41
|
+
"environment": client.env.get("name"),
|
|
42
|
+
"sends_workspaceid": "workspaceid" in headers,
|
|
43
|
+
"web_base": config.web_base(client.profile),
|
|
44
|
+
"note": ("apikey auth is validated per-request; run check-auth to hit a "
|
|
45
|
+
"live endpoint"),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def check_auth(client, _args) -> dict:
|
|
50
|
+
"""Hit a live read endpoint to confirm the credential is accepted."""
|
|
51
|
+
try:
|
|
52
|
+
body = client.get(_PROBE_PATH)
|
|
53
|
+
except ProcesioAPIError as e:
|
|
54
|
+
return {
|
|
55
|
+
"authenticated": False,
|
|
56
|
+
"profile": client.name,
|
|
57
|
+
"environment": client.env.get("name"),
|
|
58
|
+
"mode": client.profile.get("type"),
|
|
59
|
+
"probe": _PROBE_PATH,
|
|
60
|
+
"status": e.status,
|
|
61
|
+
"detail": e.details,
|
|
62
|
+
"web_base": config.web_base(client.profile),
|
|
63
|
+
"auth_base": config.auth_base(client.profile),
|
|
64
|
+
}
|
|
65
|
+
n = len(body) if isinstance(body, list) else None
|
|
66
|
+
return {
|
|
67
|
+
"authenticated": True,
|
|
68
|
+
"profile": client.name,
|
|
69
|
+
"environment": client.env.get("name"),
|
|
70
|
+
"web_base": config.web_base(client.profile),
|
|
71
|
+
"mode": client.profile.get("type"),
|
|
72
|
+
"probe": _PROBE_PATH,
|
|
73
|
+
"workspaces_visible": n,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def logout(client, _args) -> dict:
|
|
78
|
+
"""Clear the cached session (in-process + persistent), best-effort server logOut."""
|
|
79
|
+
name = client.name
|
|
80
|
+
had = (name in auth._MEM_COOKIES) or (profiles.get_token_cache(name) is not None)
|
|
81
|
+
if client.profile.get("type") == "userpass" and had:
|
|
82
|
+
try:
|
|
83
|
+
client.post("/api/Authentication/logOut")
|
|
84
|
+
except ProcesioAPIError:
|
|
85
|
+
pass
|
|
86
|
+
auth.clear_cookies(name)
|
|
87
|
+
return {"profile": name, "cleared_cached_token": had}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
ACTIONS = {
|
|
91
|
+
"login": ActionDef(
|
|
92
|
+
func=login, add_args=add_profile_arg, needs_client=True,
|
|
93
|
+
description="Acquire (userpass) or confirm (apikey) authentication; caches the token.",
|
|
94
|
+
),
|
|
95
|
+
"check-auth": ActionDef(
|
|
96
|
+
func=check_auth, add_args=add_profile_arg, needs_client=True,
|
|
97
|
+
description="Hit a live read endpoint to verify the profile authenticates.",
|
|
98
|
+
),
|
|
99
|
+
"logout": ActionDef(
|
|
100
|
+
func=logout, add_args=add_profile_arg, needs_client=True,
|
|
101
|
+
description="Clear the cached Bearer token for a userpass profile.",
|
|
102
|
+
),
|
|
103
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Curated read actions for workspaces, data types, the action catalog, stored
|
|
2
|
+
connection credentials, and API keys. All are safe GETs over exact v1.19 paths.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
from tools.procesio.actiondef import ActionDef
|
|
9
|
+
from tools.procesio.flowmodel import families
|
|
10
|
+
from tools.procesio.handlers.common import add_paging_args, add_profile_arg
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def list_workspaces(client, _args) -> dict:
|
|
14
|
+
return {"result": client.get("/api/Workspaces")}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _subworkspaces_args(p: argparse.ArgumentParser) -> None:
|
|
18
|
+
add_profile_arg(p)
|
|
19
|
+
add_paging_args(p)
|
|
20
|
+
p.add_argument("--parent-id", dest="parent_id", required=True,
|
|
21
|
+
help="master workspace GUID whose sub-workspaces to list")
|
|
22
|
+
p.add_argument("--include-removed", dest="include_removed", action="store_true",
|
|
23
|
+
help="include soft-deleted (workspaceState='removed') workspaces")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def list_subworkspaces(client, args) -> dict:
|
|
27
|
+
"""Sub-workspaces of a master. ACTIVE-ONLY by default — the raw endpoint also
|
|
28
|
+
returns soft-deleted ones (workspaceState='removed'), which the UI hides.
|
|
29
|
+
Needs owner/admin context (use the userpass `account` profile)."""
|
|
30
|
+
q = {"pageNumber": args.page, "pageItemCount": args.page_size}
|
|
31
|
+
res = client.get(f"/api/Workspace/{args.parent_id}/subworkspaces", q)
|
|
32
|
+
rows = res.get("pageItems") if isinstance(res, dict) else res
|
|
33
|
+
rows = rows if isinstance(rows, list) else []
|
|
34
|
+
if not args.include_removed:
|
|
35
|
+
rows = [w for w in rows if str(w.get("workspaceState", "")).lower() != "removed"]
|
|
36
|
+
return {"parent_id": args.parent_id, "count": len(rows),
|
|
37
|
+
"include_removed": bool(args.include_removed), "workspaces": rows}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _ws_users_args(p: argparse.ArgumentParser) -> None:
|
|
41
|
+
add_profile_arg(p)
|
|
42
|
+
add_paging_args(p)
|
|
43
|
+
p.add_argument("--target-workspace", dest="target_workspace",
|
|
44
|
+
help="targetWorkspace id (sub-workspace)")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def list_workspace_users(client, args) -> dict:
|
|
48
|
+
q = {"pageNumber": args.page, "pageItemCount": args.page_size,
|
|
49
|
+
"targetWorkspace": args.target_workspace}
|
|
50
|
+
return {"result": client.get("/api/Workspace/users", q)}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _search_args(p: argparse.ArgumentParser) -> None:
|
|
54
|
+
add_profile_arg(p)
|
|
55
|
+
add_paging_args(p)
|
|
56
|
+
p.add_argument("--search", help="searchName filter")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def list_datatypes(client, args) -> dict:
|
|
60
|
+
q = {"pageNumber": args.page, "pageItemCount": args.page_size,
|
|
61
|
+
"searchName": args.search}
|
|
62
|
+
return {"result": client.get("/api/DataTypes", q)}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _actions_args(p: argparse.ArgumentParser) -> None:
|
|
66
|
+
add_profile_arg(p)
|
|
67
|
+
p.add_argument("--filter", dest="action_filter", help="actionFilter value")
|
|
68
|
+
p.add_argument("--full", action="store_true",
|
|
69
|
+
help="the FULL raw catalog (getFullAction=true) - ~280KB, opt-in")
|
|
70
|
+
p.add_argument("--raw", action="store_true",
|
|
71
|
+
help="the raw /api/Actions list (large) instead of the compact view")
|
|
72
|
+
p.add_argument("--by-family", dest="by_family", action="store_true",
|
|
73
|
+
help="(default already groups by family; kept for back-compat)")
|
|
74
|
+
p.add_argument("--family", help="return only one family's actions")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def list_actions_catalog(client, args) -> dict:
|
|
78
|
+
q = {"actionFilter": args.action_filter,
|
|
79
|
+
"getFullAction": "true" if args.full else None}
|
|
80
|
+
res = client.get("/api/Actions", q)
|
|
81
|
+
# Default is a COMPACT family-grouped listing (name + desc per action). The full raw
|
|
82
|
+
# catalog is ~280KB - big enough to strain a small context window on its own - so it
|
|
83
|
+
# is opt-in via --full / --raw. --family filters the compact view to one family.
|
|
84
|
+
if args.full or getattr(args, "raw", False):
|
|
85
|
+
return {"result": res}
|
|
86
|
+
items = res.get("actions") if isinstance(res, dict) else res
|
|
87
|
+
items = items if isinstance(items, list) else []
|
|
88
|
+
buckets: dict[str, list] = {}
|
|
89
|
+
for a in items:
|
|
90
|
+
name = a.get("name") or a.get("Name")
|
|
91
|
+
buckets.setdefault(families.classify(name), []).append(
|
|
92
|
+
{"name": name, "icon": a.get("icon"), "shape": a.get("shape"),
|
|
93
|
+
"desc": families.describe(name)})
|
|
94
|
+
if args.family:
|
|
95
|
+
return {"result": {args.family: buckets.get(args.family, [])}}
|
|
96
|
+
return {"result": {"families": buckets}}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def list_connections(client, args) -> dict:
|
|
100
|
+
"""PROCESIO's stored connection credentials (GET /api/Credentials)."""
|
|
101
|
+
q = {"pageNumber": args.page, "pageItemCount": args.page_size,
|
|
102
|
+
"searchName": args.search}
|
|
103
|
+
return {"result": client.get("/api/Credentials", q)}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def list_connection_types(client, _args) -> dict:
|
|
107
|
+
return {"result": client.get("/api/Credentials/types")}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def list_api_keys(client, _args) -> dict:
|
|
111
|
+
return {"result": client.get("/api/ApiKey")}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
ACTIONS = {
|
|
115
|
+
"list-workspaces": ActionDef(
|
|
116
|
+
func=list_workspaces, add_args=add_profile_arg, needs_client=True,
|
|
117
|
+
description="List the caller's workspaces (GET /api/Workspaces, active-only).",
|
|
118
|
+
),
|
|
119
|
+
"list-subworkspaces": ActionDef(
|
|
120
|
+
func=list_subworkspaces, add_args=_subworkspaces_args, needs_client=True,
|
|
121
|
+
description="List a master's sub-workspaces, active-only by default (--include-removed for soft-deleted).",
|
|
122
|
+
),
|
|
123
|
+
"list-workspace-users": ActionDef(
|
|
124
|
+
func=list_workspace_users, add_args=_ws_users_args, needs_client=True,
|
|
125
|
+
description="List users in a workspace (GET /api/Workspace/users).",
|
|
126
|
+
),
|
|
127
|
+
"list-datatypes": ActionDef(
|
|
128
|
+
func=list_datatypes, add_args=_search_args, needs_client=True,
|
|
129
|
+
description="List data types (GET /api/DataTypes).",
|
|
130
|
+
),
|
|
131
|
+
"list-actions-catalog": ActionDef(
|
|
132
|
+
func=list_actions_catalog, add_args=_actions_args, needs_client=True,
|
|
133
|
+
description="List the action/connector catalog (GET /api/Actions).",
|
|
134
|
+
),
|
|
135
|
+
"list-connections": ActionDef(
|
|
136
|
+
func=list_connections, add_args=_search_args, needs_client=True,
|
|
137
|
+
description="List stored connection credentials (GET /api/Credentials).",
|
|
138
|
+
),
|
|
139
|
+
"list-connection-types": ActionDef(
|
|
140
|
+
func=list_connection_types, add_args=add_profile_arg, needs_client=True,
|
|
141
|
+
description="List supported connection types (GET /api/Credentials/types).",
|
|
142
|
+
),
|
|
143
|
+
"list-api-keys": ActionDef(
|
|
144
|
+
func=list_api_keys, add_args=add_profile_arg, needs_client=True,
|
|
145
|
+
description="List API keys in the workspace (GET /api/ApiKey).",
|
|
146
|
+
),
|
|
147
|
+
}
|