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,463 @@
|
|
|
1
|
+
"""Transport: export selected components to a `.procesio` bundle.
|
|
2
|
+
|
|
3
|
+
Wraps `POST /api/Transport/export-entities` (requires Workspace.Admin -> use the
|
|
4
|
+
userpass `account` profile). Accepts component **names, ids, or `all`** per type
|
|
5
|
+
and resolves names -> ids against the scoped workspace, builds the selection DTO,
|
|
6
|
+
exports, and saves the raw `.procesio` file. Credentials are excluded unless you
|
|
7
|
+
ask for them.
|
|
8
|
+
|
|
9
|
+
Verified end to end 2026-06-23 (see PROCESIO-API-NOTES.md).
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import json
|
|
15
|
+
import re
|
|
16
|
+
|
|
17
|
+
from tools.procesio.actiondef import ActionDef
|
|
18
|
+
from tools.procesio.errors import ProcesioAPIError, UsageError
|
|
19
|
+
from tools.procesio.handlers.common import add_profile_arg
|
|
20
|
+
|
|
21
|
+
_GUID = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-"
|
|
22
|
+
r"[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
|
|
23
|
+
|
|
24
|
+
# cli arg (dest) -> (export body key, list endpoint, extra query, name fields)
|
|
25
|
+
_RESOLVE = {
|
|
26
|
+
"data_models": ("dataModelIds", "/api/DataTypes",
|
|
27
|
+
{"includeProcesioEntries": "false", "includeExternalEntries": "true"},
|
|
28
|
+
("name", "Name")),
|
|
29
|
+
"processes": ("flowIds", "/api/Projects", {}, ("title", "name")),
|
|
30
|
+
"documents": ("documentIds", "/api/DocumentTemplate", {}, ("name", "Name")),
|
|
31
|
+
"webhooks": ("webhookIds", "/api/Webhooks", {}, ("name", "Name")),
|
|
32
|
+
"forms": ("formIds", "/api/FormTemplate", {}, ("name", "Name")),
|
|
33
|
+
"credentials": ("credentialIds", "/api/Credentials", {}, ("name", "Name")),
|
|
34
|
+
# Data stores are a first-class export category: `ExportEntitiesDto` carries
|
|
35
|
+
# `dataStoreIds`, the header form of the endpoint takes `exportDataStores`,
|
|
36
|
+
# the import endpoint takes `importDataStores`, and the pack format has a
|
|
37
|
+
# `DataStores` section. Omitting this entry meant `export` never asked for a
|
|
38
|
+
# store, so a pack silently arrived without one - and a referencing process
|
|
39
|
+
# travelled carrying a store id the receiving workspace does not have.
|
|
40
|
+
"data_stores": ("dataStoreIds", "/api/DataStore", {}, ("name", "Name")),
|
|
41
|
+
}
|
|
42
|
+
_BODY_KEYS = [v[0] for v in _RESOLVE.values()]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _list_all(client, path, extra) -> list[dict]:
|
|
46
|
+
q = {"pageNumber": 1, "pageItemCount": 500}
|
|
47
|
+
q.update(extra)
|
|
48
|
+
res = client.get(path, q)
|
|
49
|
+
if isinstance(res, list):
|
|
50
|
+
return res
|
|
51
|
+
if isinstance(res, dict):
|
|
52
|
+
for k in ("pageItems", "data", "items", "List"):
|
|
53
|
+
if isinstance(res.get(k), list):
|
|
54
|
+
return res[k]
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _id_of(item: dict):
|
|
59
|
+
return item.get("id") or item.get("Id") or item.get("gid") or item.get("Gid")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _resolve(client, spec: str, path, extra, namekeys) -> tuple[list, dict]:
|
|
63
|
+
spec = (spec or "").strip()
|
|
64
|
+
if not spec:
|
|
65
|
+
return [], {}
|
|
66
|
+
if spec.lower() == "all":
|
|
67
|
+
items = _list_all(client, path, extra)
|
|
68
|
+
return [_id_of(it) for it in items if _id_of(it)], {"all": True, "matched": len(items)}
|
|
69
|
+
items = None
|
|
70
|
+
ids, matched, unresolved = [], {}, []
|
|
71
|
+
for tok in [t.strip() for t in spec.split(",") if t.strip()]:
|
|
72
|
+
if _GUID.match(tok):
|
|
73
|
+
ids.append(tok)
|
|
74
|
+
matched[tok] = tok
|
|
75
|
+
continue
|
|
76
|
+
if items is None:
|
|
77
|
+
items = _list_all(client, path, extra)
|
|
78
|
+
found = None
|
|
79
|
+
for it in items:
|
|
80
|
+
if any(str(it.get(nk, "")).strip().lower() == tok.lower() for nk in namekeys):
|
|
81
|
+
found = _id_of(it)
|
|
82
|
+
break
|
|
83
|
+
if found:
|
|
84
|
+
ids.append(found)
|
|
85
|
+
matched[tok] = found
|
|
86
|
+
else:
|
|
87
|
+
unresolved.append(tok)
|
|
88
|
+
if unresolved:
|
|
89
|
+
raise UsageError(f"could not resolve names in {path}: {unresolved}")
|
|
90
|
+
return ids, matched
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _export_args(p: argparse.ArgumentParser) -> None:
|
|
94
|
+
add_profile_arg(p)
|
|
95
|
+
p.add_argument("--data-models", dest="data_models",
|
|
96
|
+
help="data-model names/ids/all (comma-separated)")
|
|
97
|
+
p.add_argument("--processes", help="process names (title)/ids/all (comma-separated)")
|
|
98
|
+
p.add_argument("--documents", help="document names/ids/all (comma-separated)")
|
|
99
|
+
p.add_argument("--webhooks", help="webhook names/ids/all (comma-separated)")
|
|
100
|
+
p.add_argument("--forms", help="form names/ids/all (comma-separated)")
|
|
101
|
+
p.add_argument("--credentials",
|
|
102
|
+
help="credential names/ids/all (default: none — excluded)")
|
|
103
|
+
p.add_argument("--data-stores", dest="data_stores",
|
|
104
|
+
help="data-store names/ids/all (comma-separated). A process "
|
|
105
|
+
"that reads or writes a store does NOT carry the store "
|
|
106
|
+
"itself — name it here or the pack arrives with a "
|
|
107
|
+
"dangling reference")
|
|
108
|
+
p.add_argument("--export-sensitive-data", dest="export_sensitive_data",
|
|
109
|
+
action="store_true", help="include credential secrets (default off)")
|
|
110
|
+
p.add_argument("--output", help="output .procesio path (default procesio-export.procesio)")
|
|
111
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
112
|
+
help="resolve names + build the selection, but do not export or save")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def export(client, args) -> dict:
|
|
116
|
+
if not client.workspace_id and not client.profile.get("workspace_id"):
|
|
117
|
+
raise UsageError("export is workspace-scoped — pass --workspace-id <ws>")
|
|
118
|
+
body = {"exportSensitiveData": bool(args.export_sensitive_data)}
|
|
119
|
+
resolved = {}
|
|
120
|
+
for dest, (bodykey, path, extra, namekeys) in _RESOLVE.items():
|
|
121
|
+
spec = getattr(args, dest, None)
|
|
122
|
+
ids, matched = _resolve(client, spec, path, extra, namekeys)
|
|
123
|
+
body[bodykey] = ids
|
|
124
|
+
if spec:
|
|
125
|
+
resolved[dest] = {"spec": spec, "ids": ids, "matched": matched}
|
|
126
|
+
for k in _BODY_KEYS:
|
|
127
|
+
body.setdefault(k, [])
|
|
128
|
+
if not any(body[k] for k in _BODY_KEYS):
|
|
129
|
+
raise UsageError("nothing selected to export — pass at least one of "
|
|
130
|
+
"--data-models/--processes/--documents/--webhooks/"
|
|
131
|
+
"--forms/--credentials/--data-stores")
|
|
132
|
+
if args.dry_run:
|
|
133
|
+
return {"dry_run": True, "workspace_id": client.workspace_id,
|
|
134
|
+
"resolved": resolved, "body": body}
|
|
135
|
+
|
|
136
|
+
status, content, _headers = client.request_bytes(
|
|
137
|
+
"POST", "/api/Transport/export-entities", body=body)
|
|
138
|
+
if not (200 <= status < 300):
|
|
139
|
+
raise ProcesioAPIError(status, "export failed",
|
|
140
|
+
{"body": content[:300].decode("utf-8", "replace")})
|
|
141
|
+
out = args.output or "procesio-export.procesio"
|
|
142
|
+
with open(out, "wb") as f:
|
|
143
|
+
f.write(content)
|
|
144
|
+
sections = {}
|
|
145
|
+
try:
|
|
146
|
+
doc = json.loads(content)
|
|
147
|
+
for sec in ("DataTypes", "Flows", "DocumentTemplates", "Credentials",
|
|
148
|
+
"Webhooks", "Forms", "DataStores"):
|
|
149
|
+
sections[sec] = len(doc.get(sec, []) or [])
|
|
150
|
+
except Exception: # noqa: BLE001
|
|
151
|
+
sections = {"_note": "saved, but response was not parseable JSON"}
|
|
152
|
+
return {"saved": out, "bytes": len(content), "workspace_id": client.workspace_id,
|
|
153
|
+
"sections": sections, "resolved": resolved}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# ---------------------------------------------------------------------------
|
|
157
|
+
# Data Store mapper repair
|
|
158
|
+
#
|
|
159
|
+
# The platform's EXPORT re-spells every Data Store mapper row into the Call
|
|
160
|
+
# SubProcess wire shape, and the import does not translate it back. Nothing is
|
|
161
|
+
# lost - the column name and the variable GUID both survive under different
|
|
162
|
+
# keys - so the pack passes every structural check while carrying a process
|
|
163
|
+
# that CANNOT RUN. It fails only on execution, with
|
|
164
|
+
# "A Data Store Decisional column reference cannot be null or empty."
|
|
165
|
+
#
|
|
166
|
+
# in a pack {"id": i, "process": "<flowId>.<variableId>",
|
|
167
|
+
# "document": "<COLUMN NAME>"}
|
|
168
|
+
# accepted {"id": i, "source": {"value": "<%i%>",
|
|
169
|
+
# "variable": [{"id": i, "variableId": g,
|
|
170
|
+
# "attribute": None}]},
|
|
171
|
+
# "column": "<COLUMN NAME>"}
|
|
172
|
+
#
|
|
173
|
+
# The transform is IDEMPOTENT on purpose: a row already carrying `column` is
|
|
174
|
+
# passed through untouched, so if the export is ever fixed this becomes a
|
|
175
|
+
# no-op rather than corrupting a correct pack.
|
|
176
|
+
# ---------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
def _repair_mapper_rows(rows: list) -> tuple[list, int]:
|
|
179
|
+
"""Rewrite exported mapper rows into the shape the back end accepts."""
|
|
180
|
+
out, changed = [], 0
|
|
181
|
+
for row in rows:
|
|
182
|
+
if not isinstance(row, dict) or "document" not in row:
|
|
183
|
+
out.append(row) # already accepted, or not a mapper row
|
|
184
|
+
continue
|
|
185
|
+
i = row.get("id", 0)
|
|
186
|
+
variable_id = str(row.get("process") or "").split(".")[-1]
|
|
187
|
+
out.append({
|
|
188
|
+
"id": i,
|
|
189
|
+
# the placeholder index matches the id INSIDE its own inline array
|
|
190
|
+
"source": {"value": "<%%%d%%>" % i,
|
|
191
|
+
"variable": [{"id": i, "variableId": variable_id,
|
|
192
|
+
"attribute": None}]},
|
|
193
|
+
"column": row.get("document"),
|
|
194
|
+
})
|
|
195
|
+
changed += 1
|
|
196
|
+
return out, changed
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _is_mapper_value(value) -> bool:
|
|
200
|
+
return (isinstance(value, list) and bool(value)
|
|
201
|
+
and all(isinstance(r, dict) for r in value)
|
|
202
|
+
and any("document" in r or "column" in r for r in value))
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def repair_datastore_mapper_pack(pack: dict) -> tuple[dict, int]:
|
|
206
|
+
"""Return (repaired copy, rows changed). The input is never mutated."""
|
|
207
|
+
out = json.loads(json.dumps(pack))
|
|
208
|
+
changed = 0
|
|
209
|
+
for flow in out.get("Flows") or []:
|
|
210
|
+
for action in flow.get("Actions") or []:
|
|
211
|
+
for param in action.get("Parameters") or []:
|
|
212
|
+
value = param.get("Value")
|
|
213
|
+
if not _is_mapper_value(value):
|
|
214
|
+
continue
|
|
215
|
+
rows, n = _repair_mapper_rows(value)
|
|
216
|
+
if n:
|
|
217
|
+
param["Value"] = rows
|
|
218
|
+
# the variable array belongs INSIDE the source operand.
|
|
219
|
+
# The parameter's own list stays empty.
|
|
220
|
+
param["Variable"] = param.get("Variable") or []
|
|
221
|
+
changed += n
|
|
222
|
+
return out, changed
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _repair_args(p: argparse.ArgumentParser) -> None:
|
|
226
|
+
p.add_argument("--in", dest="in_path", required=True,
|
|
227
|
+
help="the .procesio pack to repair (a path, or '-' for stdin)")
|
|
228
|
+
p.add_argument("--out", dest="out_path",
|
|
229
|
+
help="write the repaired pack here (omit to print it)")
|
|
230
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
231
|
+
help="report what would change without writing anything")
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def repair_datastore_mapper(args) -> dict:
|
|
235
|
+
import sys as _sys
|
|
236
|
+
from pathlib import Path as _Path
|
|
237
|
+
|
|
238
|
+
if args.in_path == "-":
|
|
239
|
+
raw = _sys.stdin.read()
|
|
240
|
+
else:
|
|
241
|
+
src = _Path(args.in_path)
|
|
242
|
+
if not src.is_file():
|
|
243
|
+
raise UsageError("--in is not a readable file: %s" % args.in_path)
|
|
244
|
+
raw = src.read_text(encoding="utf-8")
|
|
245
|
+
try:
|
|
246
|
+
pack = json.loads(raw)
|
|
247
|
+
except json.JSONDecodeError as e:
|
|
248
|
+
raise UsageError("--in is not valid JSON: %s" % e)
|
|
249
|
+
|
|
250
|
+
repaired, changed = repair_datastore_mapper_pack(pack)
|
|
251
|
+
blob = json.dumps(repaired, ensure_ascii=False)
|
|
252
|
+
result = {"rows_repaired": changed,
|
|
253
|
+
"already_correct": changed == 0,
|
|
254
|
+
"spelling_counts": {k: blob.count('"%s"' % k)
|
|
255
|
+
for k in ("column", "source",
|
|
256
|
+
"document", "process")},
|
|
257
|
+
"idempotent": True}
|
|
258
|
+
if args.dry_run:
|
|
259
|
+
result["written"] = None
|
|
260
|
+
result["dry_run"] = True
|
|
261
|
+
return {"result": result}
|
|
262
|
+
if args.out_path:
|
|
263
|
+
_Path(args.out_path).write_text(blob, encoding="utf-8")
|
|
264
|
+
result["written"] = args.out_path
|
|
265
|
+
else:
|
|
266
|
+
result["pack"] = repaired
|
|
267
|
+
result["written"] = None
|
|
268
|
+
return {"result": result}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# ---------------------------------------------------------------------------
|
|
272
|
+
# Webhook binding strip
|
|
273
|
+
#
|
|
274
|
+
# Everything else a process depends on is LEFT BEHIND by an export - Data Store
|
|
275
|
+
# rows, credentials - so an imported process arrives visibly incomplete and
|
|
276
|
+
# somebody provisions it. A webhook BINDING is the exception: it lives in the
|
|
277
|
+
# process definition, so it TRAVELS. The schema requires it to:
|
|
278
|
+
#
|
|
279
|
+
# webhooks/0: Additional properties are not allowed ('id' was unexpected)
|
|
280
|
+
# webhooks/0: 'webhookId' is a required property
|
|
281
|
+
#
|
|
282
|
+
# And the launch endpoint is anonymous - every verb on
|
|
283
|
+
# /api/Webhooks/launch/{id} documents "Permission required: None" - so the id
|
|
284
|
+
# IS the access control, not a name for something a permission protects.
|
|
285
|
+
#
|
|
286
|
+
# A pack therefore carries a LIVE CAPABILITY FOR THE SOURCE INSTALLATION while
|
|
287
|
+
# being LESS functional at the destination, where the id names nothing. That is
|
|
288
|
+
# the opposite failure direction from every other missing binding: the others
|
|
289
|
+
# fail closed, this one fails open. A pack is the artefact handed to a customer.
|
|
290
|
+
#
|
|
291
|
+
# TWO ARRAYS, TWO EXPOSURES, counted separately:
|
|
292
|
+
# Flows[*].Webhooks the BINDING. Travels with the flow, asked for or not
|
|
293
|
+
# Webhooks the webhook ENTITY. Only present if --webhooks was
|
|
294
|
+
# passed - but then it carries the id directly
|
|
295
|
+
#
|
|
296
|
+
# The transform is IDEMPOTENT: a pack with no webhooks is returned unchanged,
|
|
297
|
+
# and a flow with no `Webhooks` KEY does not gain one, because absence of a key
|
|
298
|
+
# and an empty array are different documents to the import.
|
|
299
|
+
#
|
|
300
|
+
# It also REPORTS residual ids found anywhere else in the pack rather than
|
|
301
|
+
# staying silent about them. A count of what was removed is not evidence that
|
|
302
|
+
# no copy survives - a launch URL pasted into a Call API parameter carries the
|
|
303
|
+
# same id, and reporting "clean" over the top of one would be worse than the
|
|
304
|
+
# leak, because the caller would stop looking.
|
|
305
|
+
# ---------------------------------------------------------------------------
|
|
306
|
+
|
|
307
|
+
_WEBHOOK_KEYS = ("Webhooks", "webhooks")
|
|
308
|
+
_ID_KEYS = ("webhookId", "WebhookId", "id", "Id")
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def _hook_ids(entries) -> list:
|
|
312
|
+
out = []
|
|
313
|
+
for e in entries or []:
|
|
314
|
+
if isinstance(e, dict):
|
|
315
|
+
for k in _ID_KEYS:
|
|
316
|
+
v = e.get(k)
|
|
317
|
+
if isinstance(v, str) and v:
|
|
318
|
+
out.append(v)
|
|
319
|
+
break
|
|
320
|
+
elif isinstance(e, str) and e:
|
|
321
|
+
out.append(e)
|
|
322
|
+
return out
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def _flow_containers(pack):
|
|
326
|
+
"""Yield every dict that could carry a per-flow webhook binding.
|
|
327
|
+
|
|
328
|
+
A pack uses PascalCase (`Flows`/`Webhooks`); a definition read back from
|
|
329
|
+
`get-process` uses camelCase (`flow`/`webhooks`). The same function checks
|
|
330
|
+
both, so it has to see both.
|
|
331
|
+
"""
|
|
332
|
+
for key in ("Flows", "flows"):
|
|
333
|
+
for flow in pack.get(key) or []:
|
|
334
|
+
if isinstance(flow, dict):
|
|
335
|
+
yield flow
|
|
336
|
+
for key in ("flow", "Flow"):
|
|
337
|
+
flow = pack.get(key)
|
|
338
|
+
if isinstance(flow, dict):
|
|
339
|
+
yield flow
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def strip_webhook_bindings_pack(pack: dict) -> tuple[dict, dict]:
|
|
343
|
+
"""Return (stripped copy, report). The input is never mutated.
|
|
344
|
+
|
|
345
|
+
The report NEVER carries an id - it is printed and logged, so it has to be
|
|
346
|
+
safe to print. Lengths and counts only.
|
|
347
|
+
"""
|
|
348
|
+
out = json.loads(json.dumps(pack))
|
|
349
|
+
removed_ids, flows_unbound = [], []
|
|
350
|
+
bindings = entities = 0
|
|
351
|
+
|
|
352
|
+
for flow in _flow_containers(out):
|
|
353
|
+
for key in _WEBHOOK_KEYS:
|
|
354
|
+
if key not in flow:
|
|
355
|
+
continue # ⚠ absent is not empty
|
|
356
|
+
ids = _hook_ids(flow.get(key))
|
|
357
|
+
if flow.get(key):
|
|
358
|
+
bindings += len(flow[key])
|
|
359
|
+
removed_ids += ids
|
|
360
|
+
fid = flow.get("Id") or flow.get("id")
|
|
361
|
+
if fid:
|
|
362
|
+
flows_unbound.append(fid)
|
|
363
|
+
flow[key] = []
|
|
364
|
+
|
|
365
|
+
for key in _WEBHOOK_KEYS:
|
|
366
|
+
if key in out and isinstance(out.get(key), list) and out[key]:
|
|
367
|
+
entities += len(out[key])
|
|
368
|
+
removed_ids += _hook_ids(out[key])
|
|
369
|
+
out[key] = []
|
|
370
|
+
|
|
371
|
+
# ⚠ Now look for the ids ANYWHERE ELSE, in the serialised artefact, both
|
|
372
|
+
# verbatim and dash-stripped. This is the check that makes "clean" mean
|
|
373
|
+
# something: a launch URL in a parameter carries the same capability.
|
|
374
|
+
blob = json.dumps(out, ensure_ascii=False)
|
|
375
|
+
dashless = blob.replace("-", "")
|
|
376
|
+
# Independent of what was removed: a launch URL anywhere in the pack carries the same
|
|
377
|
+
# capability, whether or not a binding was present to strip.
|
|
378
|
+
launch_urls = len(re.findall(r"Webhooks/launch/", blob, flags=re.IGNORECASE))
|
|
379
|
+
residual = sum(1 for i in set(removed_ids)
|
|
380
|
+
if i in blob or i.replace("-", "") in dashless)
|
|
381
|
+
|
|
382
|
+
return out, {
|
|
383
|
+
"flow_bindings_removed": bindings,
|
|
384
|
+
"webhook_entities_removed": entities,
|
|
385
|
+
"flows_unbound": flows_unbound,
|
|
386
|
+
"residual_ids_found": residual,
|
|
387
|
+
"launch_urls_found": launch_urls,
|
|
388
|
+
"clean": residual == 0 and launch_urls == 0,
|
|
389
|
+
"already_clean": bindings == 0 and entities == 0,
|
|
390
|
+
"idempotent": True,
|
|
391
|
+
"note": ("a webhook binding travels in a pack and the launch endpoint "
|
|
392
|
+
"is anonymous, so the id is the access control; this report "
|
|
393
|
+
"carries no ids because it is printed"),
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _strip_args(p: argparse.ArgumentParser) -> None:
|
|
398
|
+
p.add_argument("--in", dest="in_path", required=True,
|
|
399
|
+
help="the .procesio pack to strip (a path, or '-' for stdin)")
|
|
400
|
+
p.add_argument("--out", dest="out_path",
|
|
401
|
+
help="write the stripped pack here (omit to print it)")
|
|
402
|
+
p.add_argument("--dry-run", dest="dry_run", action="store_true",
|
|
403
|
+
help="report what would change without writing anything")
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def strip_webhook_bindings(args) -> dict:
|
|
407
|
+
import sys as _sys
|
|
408
|
+
from pathlib import Path as _Path
|
|
409
|
+
|
|
410
|
+
if args.in_path == "-":
|
|
411
|
+
raw = _sys.stdin.read()
|
|
412
|
+
else:
|
|
413
|
+
src = _Path(args.in_path)
|
|
414
|
+
if not src.is_file():
|
|
415
|
+
raise UsageError("--in is not a readable file: %s" % args.in_path)
|
|
416
|
+
raw = src.read_text(encoding="utf-8")
|
|
417
|
+
try:
|
|
418
|
+
pack = json.loads(raw)
|
|
419
|
+
except json.JSONDecodeError as e:
|
|
420
|
+
raise UsageError("--in is not valid JSON: %s" % e)
|
|
421
|
+
|
|
422
|
+
stripped, report = strip_webhook_bindings_pack(pack)
|
|
423
|
+
result = dict(report)
|
|
424
|
+
if args.dry_run:
|
|
425
|
+
result["written"] = None
|
|
426
|
+
result["dry_run"] = True
|
|
427
|
+
return {"result": result}
|
|
428
|
+
if args.out_path:
|
|
429
|
+
_Path(args.out_path).write_text(
|
|
430
|
+
json.dumps(stripped, ensure_ascii=False), encoding="utf-8")
|
|
431
|
+
result["written"] = args.out_path
|
|
432
|
+
else:
|
|
433
|
+
result["pack"] = stripped
|
|
434
|
+
result["written"] = None
|
|
435
|
+
return {"result": result}
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
ACTIONS = {
|
|
439
|
+
"export": ActionDef(
|
|
440
|
+
func=export, add_args=_export_args, needs_client=True,
|
|
441
|
+
description=("Export components to a .procesio file (Transport). Accepts "
|
|
442
|
+
"names/ids/all per type; credentials excluded by default; "
|
|
443
|
+
"--dry-run to preview the selection."),
|
|
444
|
+
),
|
|
445
|
+
"repair-datastore-mapper": ActionDef(
|
|
446
|
+
func=repair_datastore_mapper, add_args=_repair_args, needs_client=False,
|
|
447
|
+
description=("Repair a .procesio pack whose Data Store mapper the export "
|
|
448
|
+
"re-spelled into the refused `document`/`process` form "
|
|
449
|
+
"(offline). An imported process carrying the exported form "
|
|
450
|
+
"cannot run. Idempotent: an already-correct pack is "
|
|
451
|
+
"unchanged."),
|
|
452
|
+
),
|
|
453
|
+
"strip-webhook-bindings": ActionDef(
|
|
454
|
+
func=strip_webhook_bindings, add_args=_strip_args, needs_client=False,
|
|
455
|
+
description=("Strip webhook bindings from a .procesio pack (offline). A "
|
|
456
|
+
"binding lives in the process definition, so it TRAVELS - "
|
|
457
|
+
"and the launch endpoint is anonymous, so the id it carries "
|
|
458
|
+
"is a live capability for the SOURCE installation. Removes "
|
|
459
|
+
"the per-flow bindings and any top-level webhook entities, "
|
|
460
|
+
"counted separately, and reports any id still present "
|
|
461
|
+
"elsewhere. Idempotent."),
|
|
462
|
+
),
|
|
463
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""Generate the platform usage guide FROM the notes, so it cannot drift from them.
|
|
2
|
+
|
|
3
|
+
The notes hold several hundred sections across twenty files, and the ones a builder
|
|
4
|
+
must know before touching the platform are marked in them with a `⚠`. That marker is
|
|
5
|
+
the authors' own signal for "this is a rule, not background", and it is what this reads.
|
|
6
|
+
|
|
7
|
+
Why generated rather than written. The same knowledge has to reach two audiences: us,
|
|
8
|
+
in this repo, and whoever clones the public one. A second document restating the rules
|
|
9
|
+
would create two copies of every sentence, and the copy is the one that goes stale: the
|
|
10
|
+
note gets corrected during the work that corrects the behaviour, and nobody remembers
|
|
11
|
+
the summary. So the guide carries the RULE LINE and a pointer, never the explanation.
|
|
12
|
+
The explanation stays in the note, one copy, and the guide is regenerated. Nothing here
|
|
13
|
+
is authored by hand, exactly like SKILL.md and the capability router.
|
|
14
|
+
|
|
15
|
+
It lands in the tool's own folder, so the publication plan carries it to the public repo
|
|
16
|
+
with everything else under `tools/procesio/` - no plan entry, no second maintenance path.
|
|
17
|
+
|
|
18
|
+
Deterministic on purpose: no clock, no counts that shift with an unrelated edit, stable
|
|
19
|
+
ordering. A generated file that changes when nothing changed is one people stop reading
|
|
20
|
+
diffs for.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import re
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
from tools.procesio.actiondef import ActionDef
|
|
29
|
+
|
|
30
|
+
TOOL_DIR = Path(__file__).resolve().parents[1]
|
|
31
|
+
GUIDE_NAME = "PROCESIO-USAGE-GUIDE.md"
|
|
32
|
+
|
|
33
|
+
# Generated or navigational, not sources of rules.
|
|
34
|
+
SKIP = {GUIDE_NAME, "SKILL.md", "README.md"}
|
|
35
|
+
|
|
36
|
+
# A note file's topic, for grouping. Anything unlisted falls back to a prettified
|
|
37
|
+
# filename, so a new note appears in the guide without touching this map.
|
|
38
|
+
TOPICS = {
|
|
39
|
+
"PROCESIO-API-NOTES.md": "The API, and what its answers actually mean",
|
|
40
|
+
"PROCESIO-API-CORRECTIONS.md": "Readings that turned out to be wrong",
|
|
41
|
+
"PROCESIO-SQL-ACTIONS-NOTES.md": "SQL actions",
|
|
42
|
+
"PROCESIO-RESOURCE-MODEL-NOTES.md": "Building resources: processes, forms, documents",
|
|
43
|
+
"PROCESIO-PYTHON-ACTION-NOTES.md": "The Python action",
|
|
44
|
+
"PROCESIO-NODE-MODULE-WHITELIST.md": "The Node action and its libraries",
|
|
45
|
+
"PROCESIO-SEND-EMAIL-NOTES.md": "Send Email",
|
|
46
|
+
"PROCESIO-FORM-SUBMISSION-NOTES.md": "Form submission",
|
|
47
|
+
"PROCESIO-FE-VALIDATION-NOTES.md": "Designer-side validation",
|
|
48
|
+
"PROCESIO-FORM-API-HANG-NOTE.md": "Forms: a call that never returns",
|
|
49
|
+
"PROCESIO-METERING-NOTES.md": "Metering and consumption",
|
|
50
|
+
"PROCESIO-AUTH-NOTES.md": "Authentication",
|
|
51
|
+
"PROCESIO-ENVIRONMENTS-NOTES.md": "Environments",
|
|
52
|
+
"PROCESIO-CUSTOM-ACTION-NOTES.md": "Custom actions",
|
|
53
|
+
"PROCESIO-CARD-BUILD-NOTES.md": "Building a card",
|
|
54
|
+
"PROCESIO-RECONCILIATION-PATTERNS.md": "Reconciling state",
|
|
55
|
+
"PROCESIO-DOCS-FIX-REPORT.md": "Corrections sent to the documentation",
|
|
56
|
+
"PHASE4-E2E-NOTES.md": "End-to-end build, from a real one",
|
|
57
|
+
"DTO-SUBTOOLS-NOTE.md": "The DTO builders",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_HEADING = re.compile(r"^(#{2,4})\s+(.*)$")
|
|
61
|
+
_MD_NOISE = re.compile(r"[`*_]")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _clean(text: str) -> str:
|
|
65
|
+
"""A rule as one readable line: markers, emphasis and trailing dates removed."""
|
|
66
|
+
t = text.replace("⚠", " ").strip()
|
|
67
|
+
t = _MD_NOISE.sub("", t)
|
|
68
|
+
# A trailing provenance stamp is evidence for the note, noise in an index:
|
|
69
|
+
# (verified 2026-06-24), (live 31/08/2026), (2026-08-24) all go.
|
|
70
|
+
t = re.sub(r"\s*\((?:live|verified|measured|seen|confirmed)?[ ,-]*\d{1,4}[/-]\d{1,2}[/-]\d{1,4}\)\s*$", "", t, flags=re.I)
|
|
71
|
+
t = re.sub(r"\s{2,}", " ", t)
|
|
72
|
+
# Removing the marker can leave "( bites parsers)" or " ,".
|
|
73
|
+
t = re.sub(r"\(\s+", "(", t)
|
|
74
|
+
t = re.sub(r"\s+([),;:])", r"\1", t)
|
|
75
|
+
return t.strip(" .:-")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _anchor(heading: str) -> str:
|
|
79
|
+
"""GitHub's heading slug, so a link lands on the section itself."""
|
|
80
|
+
s = _clean(heading).lower()
|
|
81
|
+
s = re.sub(r"[^\w\s-]", "", s)
|
|
82
|
+
return re.sub(r"\s+", "-", s).strip("-")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def collect(tool_dir: Path | None = None) -> tuple[list[dict], list[str]]:
|
|
86
|
+
"""One entry per SECTION that carries a ⚠, plus the notes that carry none.
|
|
87
|
+
|
|
88
|
+
Section-level, not marker-level, and that is the whole design. A first version
|
|
89
|
+
emitted one entry per marker and produced fragments: a section often carries
|
|
90
|
+
several ⚠ paragraphs continuing one argument, so the list filled with half
|
|
91
|
+
sentences that mean nothing away from the paragraph above them, and several
|
|
92
|
+
entries pointed at the same anchor.
|
|
93
|
+
|
|
94
|
+
A section is the unit a reader navigates to, its heading is a complete statement,
|
|
95
|
+
and it de-duplicates by construction. The marker count still says how much evidence
|
|
96
|
+
sits under an entry, so it is carried rather than shown as separate rows.
|
|
97
|
+
|
|
98
|
+
The second return value is the notes with no marked section at all. The convention
|
|
99
|
+
is applied in only some files today, and a guide that silently omitted the rest
|
|
100
|
+
would read as though they hold nothing worth knowing.
|
|
101
|
+
"""
|
|
102
|
+
root = tool_dir or TOOL_DIR
|
|
103
|
+
out: list[dict] = []
|
|
104
|
+
unmarked: list[str] = []
|
|
105
|
+
for path in sorted(root.glob("*.md")):
|
|
106
|
+
if path.name in SKIP:
|
|
107
|
+
continue
|
|
108
|
+
lines = path.read_text(encoding="utf-8", errors="replace").split("\n")
|
|
109
|
+
sections: list[dict] = []
|
|
110
|
+
cur: dict | None = None
|
|
111
|
+
for i, raw in enumerate(lines, start=1):
|
|
112
|
+
head = _HEADING.match(raw)
|
|
113
|
+
if head:
|
|
114
|
+
cur = {"file": path.name, "line": i, "rule": _clean(head.group(2)),
|
|
115
|
+
"anchor": _anchor(head.group(2)),
|
|
116
|
+
"marks": 1 if "⚠" in raw else 0}
|
|
117
|
+
sections.append(cur)
|
|
118
|
+
continue
|
|
119
|
+
if cur is not None and "⚠" in raw:
|
|
120
|
+
cur["marks"] += 1
|
|
121
|
+
marked = [s for s in sections if s["marks"] and len(s["rule"]) >= 4]
|
|
122
|
+
if marked:
|
|
123
|
+
out.extend(marked)
|
|
124
|
+
else:
|
|
125
|
+
unmarked.append(path.name)
|
|
126
|
+
return out, unmarked
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def render(items: list[dict], unmarked: list[str]) -> str:
|
|
130
|
+
by_file: dict[str, list[dict]] = {}
|
|
131
|
+
for it in items:
|
|
132
|
+
by_file.setdefault(it["file"], []).append(it)
|
|
133
|
+
|
|
134
|
+
L: list[str] = []
|
|
135
|
+
L.append("# Using PROCESIO: the rules that are not obvious")
|
|
136
|
+
L.append("")
|
|
137
|
+
L.append("**Generated from the notes in this folder. Do not edit by hand.**")
|
|
138
|
+
L.append("Regenerate with `python scripts/run-tool.py procesio usage-guide`.")
|
|
139
|
+
L.append("")
|
|
140
|
+
L.append("Every rule below was learned by losing time to it against the live platform,")
|
|
141
|
+
L.append("and they share a shape: the call succeeds, the status says finished, nothing")
|
|
142
|
+
L.append("is logged, and the thing you asked for did not happen. That is what makes")
|
|
143
|
+
L.append("them expensive. There is no error to search for, so you look in the wrong")
|
|
144
|
+
L.append("place.")
|
|
145
|
+
L.append("")
|
|
146
|
+
L.append("None of these is a defect report. Each is the platform doing something")
|
|
147
|
+
L.append("defensible that reads as a failure until you know the rule.")
|
|
148
|
+
L.append("")
|
|
149
|
+
L.append("This page carries the rule and a pointer. The reasoning, the measurement and")
|
|
150
|
+
L.append("the worked example stay in the note it points at, one copy, so a correction")
|
|
151
|
+
L.append("lands in exactly one place and this page follows on the next build.")
|
|
152
|
+
L.append("")
|
|
153
|
+
L.append(f"**{len(items)} rules across {len(by_file)} notes.**")
|
|
154
|
+
L.append("")
|
|
155
|
+
|
|
156
|
+
for name in sorted(by_file, key=lambda n: (-len(by_file[n]), n)):
|
|
157
|
+
L.append(f"## {TOPICS.get(name, name.replace('.md', '').replace('-', ' ').title())}")
|
|
158
|
+
L.append("")
|
|
159
|
+
L.append(f"Source: [`{name}`]({name})")
|
|
160
|
+
L.append("")
|
|
161
|
+
for it in by_file[name]:
|
|
162
|
+
target = f"{name}#{it['anchor']}" if it["anchor"] else name
|
|
163
|
+
L.append(f"- [{it['rule']}]({target})")
|
|
164
|
+
L.append("")
|
|
165
|
+
|
|
166
|
+
if unmarked:
|
|
167
|
+
L.append("## Notes not yet indexed here")
|
|
168
|
+
L.append("")
|
|
169
|
+
L.append("These carry rules too. They are absent because the `⚠` convention has not")
|
|
170
|
+
L.append("been applied to them yet, not because they hold nothing. Marking a rule in")
|
|
171
|
+
L.append("one of them adds it here on the next build; read them directly meanwhile.")
|
|
172
|
+
L.append("")
|
|
173
|
+
for name in sorted(unmarked):
|
|
174
|
+
L.append(f"- [`{name}`]({name})")
|
|
175
|
+
L.append("")
|
|
176
|
+
return "\n".join(L).rstrip() + "\n"
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def usage_guide(args) -> dict:
|
|
180
|
+
items, unmarked = collect()
|
|
181
|
+
text = render(items, unmarked)
|
|
182
|
+
out = Path(args.out) if getattr(args, "out", None) else TOOL_DIR / GUIDE_NAME
|
|
183
|
+
current = out.read_text(encoding="utf-8") if out.exists() else ""
|
|
184
|
+
stale = current != text
|
|
185
|
+
payload = {
|
|
186
|
+
"action": "usage-guide",
|
|
187
|
+
"rules": len(items),
|
|
188
|
+
"notes_with_rules": len({i["file"] for i in items}),
|
|
189
|
+
"notes_not_yet_marked": unmarked,
|
|
190
|
+
"path": str(out),
|
|
191
|
+
"stale": stale,
|
|
192
|
+
}
|
|
193
|
+
if getattr(args, "check", False):
|
|
194
|
+
payload["wrote"] = False
|
|
195
|
+
if stale:
|
|
196
|
+
payload["hint"] = ("out of date - run `procesio usage-guide` to regenerate "
|
|
197
|
+
"(a note changed, or a new one was added)")
|
|
198
|
+
return payload
|
|
199
|
+
# newline="" keeps LF: this file is published, and a CRLF rewrite would show the
|
|
200
|
+
# whole guide as modified in the public repo's first diff.
|
|
201
|
+
out.write_text(text, encoding="utf-8", newline="")
|
|
202
|
+
payload["wrote"] = True
|
|
203
|
+
payload["bytes"] = out.stat().st_size
|
|
204
|
+
return payload
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _args(p: argparse.ArgumentParser) -> None:
|
|
208
|
+
p.add_argument("--check", action="store_true",
|
|
209
|
+
help="Report whether the guide is out of date; write nothing.")
|
|
210
|
+
p.add_argument("--out", help="Write somewhere other than the tool folder.")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
ACTIONS = {
|
|
214
|
+
"usage-guide": ActionDef(
|
|
215
|
+
func=usage_guide, add_args=_args, needs_client=False,
|
|
216
|
+
description="Regenerate PROCESIO-USAGE-GUIDE.md from the rules the notes in this "
|
|
217
|
+
"folder mark with a warning sign (offline, deterministic). The guide "
|
|
218
|
+
"carries the rule and a link; the explanation stays in the note, so "
|
|
219
|
+
"there is one copy of every fact. It ships to the public repo with "
|
|
220
|
+
"the rest of the folder. --check reports staleness without writing.",
|
|
221
|
+
),
|
|
222
|
+
}
|