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,91 @@
|
|
|
1
|
+
"""Pure reader for .xlsx / .xlsm workbooks (openpyxl), kept import-light and
|
|
2
|
+
unit-testable. The handlers in main.py wrap these into JSON actions.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _load(path: str, data_only: bool = True):
|
|
10
|
+
from openpyxl import load_workbook
|
|
11
|
+
p = Path(path)
|
|
12
|
+
if not p.exists():
|
|
13
|
+
raise FileNotFoundError(f"file not found: {path}")
|
|
14
|
+
if p.suffix.lower() not in (".xlsx", ".xlsm"):
|
|
15
|
+
raise ValueError(f"not an .xlsx/.xlsm file: {path}")
|
|
16
|
+
return load_workbook(str(p), data_only=data_only)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def list_sheets(path: str) -> list[dict]:
|
|
20
|
+
"""Return [{title, rows, columns}] for every worksheet."""
|
|
21
|
+
wb = _load(path)
|
|
22
|
+
out = []
|
|
23
|
+
for ws in wb.worksheets:
|
|
24
|
+
out.append({
|
|
25
|
+
"title": ws.title,
|
|
26
|
+
"rows": ws.max_row,
|
|
27
|
+
"columns": ws.max_column,
|
|
28
|
+
})
|
|
29
|
+
return out
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _trim_row(row: tuple) -> list:
|
|
33
|
+
"""Drop trailing empty cells; stringify everything (None -> '')."""
|
|
34
|
+
vals = list(row)
|
|
35
|
+
while vals and (vals[-1] is None or str(vals[-1]).strip() == ""):
|
|
36
|
+
vals.pop()
|
|
37
|
+
return ["" if v is None else v for v in vals]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _is_empty(vals: list) -> bool:
|
|
41
|
+
return all(v is None or str(v).strip() == "" for v in vals)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def read_sheet(path: str, sheet: str | None = None, *,
|
|
45
|
+
max_rows: int | None = None, skip_empty: bool = True) -> dict:
|
|
46
|
+
"""Return {sheet, rows: [[...]], truncated} for one worksheet.
|
|
47
|
+
|
|
48
|
+
sheet=None reads the first/active worksheet. Cell values are JSON-safe
|
|
49
|
+
(numbers/strings/bools; dates become their string form via openpyxl)."""
|
|
50
|
+
wb = _load(path)
|
|
51
|
+
ws = wb[sheet] if sheet else wb.worksheets[0]
|
|
52
|
+
rows: list[list] = []
|
|
53
|
+
truncated = False
|
|
54
|
+
for r in ws.iter_rows(values_only=True):
|
|
55
|
+
vals = _trim_row(r)
|
|
56
|
+
if skip_empty and _is_empty(vals):
|
|
57
|
+
continue
|
|
58
|
+
rows.append([_json_safe(v) for v in vals])
|
|
59
|
+
if max_rows is not None and len(rows) >= max_rows:
|
|
60
|
+
truncated = True
|
|
61
|
+
break
|
|
62
|
+
return {"sheet": ws.title, "rows": rows, "truncated": truncated}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _json_safe(v):
|
|
66
|
+
import datetime
|
|
67
|
+
if isinstance(v, (datetime.datetime, datetime.date, datetime.time)):
|
|
68
|
+
return v.isoformat()
|
|
69
|
+
return v
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def dump_text(path: str, *, max_rows: int | None = None) -> str:
|
|
73
|
+
"""Whole workbook as readable pipe-delimited text (one row per line,
|
|
74
|
+
empty rows skipped), with sheet headers. Mirrors the original ad-hoc dump."""
|
|
75
|
+
wb = _load(path)
|
|
76
|
+
lines = [f"### FILE: {path}", f"### SHEETS: {wb.sheetnames}", ""]
|
|
77
|
+
for ws in wb.worksheets:
|
|
78
|
+
lines.append(f"\n===== SHEET: {ws.title} (dims {ws.dimensions}) =====")
|
|
79
|
+
shown = 0
|
|
80
|
+
for i, r in enumerate(ws.iter_rows(values_only=True), start=1):
|
|
81
|
+
vals = _trim_row(r)
|
|
82
|
+
if _is_empty(vals):
|
|
83
|
+
continue
|
|
84
|
+
lines.append(f"r{i}: " + " | ".join(str(_json_safe(v)) for v in vals))
|
|
85
|
+
shown += 1
|
|
86
|
+
if max_rows is not None and shown >= max_rows:
|
|
87
|
+
lines.append(f"... [truncated at {max_rows} non-empty rows]")
|
|
88
|
+
break
|
|
89
|
+
if shown == 0:
|
|
90
|
+
lines.append("(empty)")
|
|
91
|
+
return "\n".join(lines)
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Fixtures for the xlsx tool: sys.path + a generated sample workbook."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
# openpyxl is an OPTIONAL dependency (reading .xlsx workbooks), so a plain install does not
|
|
10
|
+
# have it. These tests then FAIL, which reads as a broken repository rather
|
|
11
|
+
# than as an extra nobody asked for. Skip instead, with the reason visible.
|
|
12
|
+
#
|
|
13
|
+
# exc_type matters: pytest 9 skips only on ModuleNotFoundError by default,
|
|
14
|
+
# and a package can be installed yet unimportable - openpyxl on a runner
|
|
15
|
+
# without its native library raises a plain ImportError, which would
|
|
16
|
+
# otherwise re-raise and take collection down instead of skipping.
|
|
17
|
+
pytest.importorskip('openpyxl', reason="install the extra that provides openpyxl",
|
|
18
|
+
exc_type=ImportError)
|
|
19
|
+
|
|
20
|
+
FRAMEWORK_ROOT = Path(__file__).resolve().parents[3]
|
|
21
|
+
if str(FRAMEWORK_ROOT) not in sys.path:
|
|
22
|
+
sys.path.insert(0, str(FRAMEWORK_ROOT))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@pytest.fixture
|
|
26
|
+
def sample_xlsx(tmp_path):
|
|
27
|
+
"""A 2-sheet workbook with a header row, data, a blank row, and diacritics."""
|
|
28
|
+
from openpyxl import Workbook
|
|
29
|
+
wb = Workbook()
|
|
30
|
+
ws1 = wb.active
|
|
31
|
+
ws1.title = "Data"
|
|
32
|
+
ws1.append(["Item", "Cost", "Notă"])
|
|
33
|
+
ws1.append(["Hosting", 1200, "lunară"])
|
|
34
|
+
ws1.append([None, None, None]) # blank row -> skipped
|
|
35
|
+
ws1.append(["Support", 800, "ăîâșț"])
|
|
36
|
+
ws2 = wb.create_sheet("Empty")
|
|
37
|
+
p = tmp_path / "sample.xlsx"
|
|
38
|
+
wb.save(str(p))
|
|
39
|
+
return str(p)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Tests for the xlsx tool: pure reader + dispatch + manifest sync."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from tools._lib.manifest import load_tool
|
|
9
|
+
from tools.xlsx import main, reader
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# --- pure reader ------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
def test_list_sheets(sample_xlsx):
|
|
15
|
+
sheets = reader.list_sheets(sample_xlsx)
|
|
16
|
+
titles = [s["title"] for s in sheets]
|
|
17
|
+
assert titles == ["Data", "Empty"]
|
|
18
|
+
data = next(s for s in sheets if s["title"] == "Data")
|
|
19
|
+
assert data["columns"] == 3
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_read_sheet_skips_empty_and_trims(sample_xlsx):
|
|
23
|
+
out = reader.read_sheet(sample_xlsx, "Data")
|
|
24
|
+
assert out["sheet"] == "Data"
|
|
25
|
+
# Blank middle row dropped: header + 2 data rows.
|
|
26
|
+
assert out["rows"] == [
|
|
27
|
+
["Item", "Cost", "Notă"],
|
|
28
|
+
["Hosting", 1200, "lunară"],
|
|
29
|
+
["Support", 800, "ăîâșț"],
|
|
30
|
+
]
|
|
31
|
+
assert out["truncated"] is False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_read_sheet_default_first(sample_xlsx):
|
|
35
|
+
out = reader.read_sheet(sample_xlsx)
|
|
36
|
+
assert out["sheet"] == "Data"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_read_sheet_max_rows(sample_xlsx):
|
|
40
|
+
out = reader.read_sheet(sample_xlsx, "Data", max_rows=1)
|
|
41
|
+
assert len(out["rows"]) == 1
|
|
42
|
+
assert out["truncated"] is True
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_read_empty_sheet(sample_xlsx):
|
|
46
|
+
out = reader.read_sheet(sample_xlsx, "Empty")
|
|
47
|
+
assert out["rows"] == []
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_dump_text(sample_xlsx):
|
|
51
|
+
text = reader.dump_text(sample_xlsx)
|
|
52
|
+
assert "SHEET: Data" in text
|
|
53
|
+
assert "Hosting | 1200 | lunară" in text
|
|
54
|
+
assert "ăîâșț" in text
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_missing_file():
|
|
58
|
+
with pytest.raises(FileNotFoundError):
|
|
59
|
+
reader.list_sheets("nope.xlsx")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_wrong_extension(tmp_path):
|
|
63
|
+
p = tmp_path / "x.csv"
|
|
64
|
+
p.write_text("a,b\n")
|
|
65
|
+
with pytest.raises(ValueError):
|
|
66
|
+
reader.list_sheets(str(p))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# --- dispatch ---------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
def test_dispatch_list_sheets(sample_xlsx):
|
|
72
|
+
result = main.dispatch("list-sheets", ["--path", sample_xlsx])
|
|
73
|
+
assert [s["title"] for s in result["sheets"]] == ["Data", "Empty"]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_dispatch_read_sheet(sample_xlsx):
|
|
77
|
+
result = main.dispatch("read-sheet", ["--path", sample_xlsx, "--sheet", "Data"])
|
|
78
|
+
assert result["rows"][0] == ["Item", "Cost", "Notă"]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_dispatch_dump_save(sample_xlsx, tmp_path):
|
|
82
|
+
out = tmp_path / "dump.txt"
|
|
83
|
+
result = main.dispatch("dump", ["--path", sample_xlsx, "--save", str(out)])
|
|
84
|
+
assert out.read_text(encoding="utf-8").count("SHEET:") == 2
|
|
85
|
+
assert result["savedTo"] == str(out.resolve())
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_dispatch_unknown_action():
|
|
89
|
+
with pytest.raises(main.UsageError):
|
|
90
|
+
main.dispatch("nope", [])
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_dispatch_missing_required_arg():
|
|
94
|
+
with pytest.raises(main.UsageError):
|
|
95
|
+
main.dispatch("list-sheets", [])
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# --- manifest sync ----------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
def test_manifest_sync():
|
|
101
|
+
tool_root = Path(main.__file__).resolve().parent
|
|
102
|
+
m = load_tool(tool_root / "tool.yaml")
|
|
103
|
+
assert set(m.action_names()) == set(main.ACTIONS)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: xlsx
|
|
2
|
+
description: Read local Excel (.xlsx/.xlsm) workbooks - list sheets, read a sheet as JSON, or dump the whole file to text. No credentials.
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
runtime: python
|
|
5
|
+
entrypoint: main.py
|
|
6
|
+
|
|
7
|
+
secrets: []
|
|
8
|
+
|
|
9
|
+
actions:
|
|
10
|
+
- name: list-sheets
|
|
11
|
+
description: List a workbook's sheets with row/column counts.
|
|
12
|
+
args:
|
|
13
|
+
- {name: path, type: string, required: true, description: Local .xlsx/.xlsm file}
|
|
14
|
+
output_schema: '{ "path": "...", "sheets": [ {title, rows, columns} ] }'
|
|
15
|
+
|
|
16
|
+
- name: read-sheet
|
|
17
|
+
description: Read one sheet's rows as a JSON 2D array (trailing-empty cells trimmed, empty rows skipped).
|
|
18
|
+
args:
|
|
19
|
+
- {name: path, type: string, required: true}
|
|
20
|
+
- {name: sheet, type: string, description: Sheet name (default first/active)}
|
|
21
|
+
- {name: max-results, type: integer, description: Cap rows returned}
|
|
22
|
+
output_schema: '{ "sheet": "...", "rows": [[...]], "truncated": false }'
|
|
23
|
+
|
|
24
|
+
- name: dump
|
|
25
|
+
description: Dump the whole workbook to readable pipe-delimited text.
|
|
26
|
+
args:
|
|
27
|
+
- {name: path, type: string, required: true}
|
|
28
|
+
- {name: save, type: string, description: Write text dump here instead of inline}
|
|
29
|
+
- {name: max-results, type: integer, description: Cap rows per sheet}
|
|
30
|
+
output_schema: '{ "text"?: "...", "savedTo"?: "...", "characters": N }'
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# aat-mcp — connection & mechanics notes
|
|
2
|
+
|
|
3
|
+
Durable notes on how the bridge connects and non-obvious mechanics (Hard rules 6, 7).
|
|
4
|
+
|
|
5
|
+
## How opencode connects to it
|
|
6
|
+
|
|
7
|
+
opencode is an MCP **client**; aat-mcp is a **local (stdio)** MCP server. Wiring lives
|
|
8
|
+
in `webplatform/spike/opencode.json`:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
"mcp": {
|
|
12
|
+
"aat": {
|
|
13
|
+
"type": "local",
|
|
14
|
+
"command": ["<abs>/.venv/Scripts/python.exe", "<abs>/webplatform/aat_mcp/server.py"],
|
|
15
|
+
"enabled": true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- **Absolute paths** in the command: robust to opencode's spawn cwd, and space-safe
|
|
21
|
+
because each element is a separate argv entry. Machine-local for the spike; the
|
|
22
|
+
container image (spec 05) will use image paths + HTTP transport.
|
|
23
|
+
- opencode spawns the server as a child of its own process (started by
|
|
24
|
+
`run-spike.cmd`, which put `.venv\Scripts` on PATH), so the server runs on the
|
|
25
|
+
framework venv. `server.py` and `bridge.py` resolve paths from `__file__`
|
|
26
|
+
(absolute), so cwd does not matter.
|
|
27
|
+
- The model is nudged to prefer these tools over bash via
|
|
28
|
+
`webplatform/spike/MCP-HINT.md` (added to opencode `instructions`).
|
|
29
|
+
|
|
30
|
+
## Protocol
|
|
31
|
+
|
|
32
|
+
- Transport: newline-delimited JSON-RPC 2.0 over stdio. One JSON object per line;
|
|
33
|
+
responses flushed immediately. stdout is reconfigured to `newline="\n"` so Windows
|
|
34
|
+
does not inject `\r\n` into the protocol stream. **stdout is the protocol channel —
|
|
35
|
+
all logs go to stderr** (`_log`).
|
|
36
|
+
- Methods handled: `server/discover`, `initialize`, `notifications/*` (swallowed, no
|
|
37
|
+
response), `ping`, `tools/list`, `tools/call`. Unknown request methods → JSON-RPC
|
|
38
|
+
`-32601`. The mechanics live once, in `protocol.py`, shared by both servers; see
|
|
39
|
+
"Protocol eras" below.
|
|
40
|
+
- `tools/call` never raises: tool failures (incl. unknown capability, KeyError) come
|
|
41
|
+
back as `{content:[{type:text,text:<json>}], isError:true}` so the model can read
|
|
42
|
+
the error.
|
|
43
|
+
|
|
44
|
+
## Protocol eras and version negotiation
|
|
45
|
+
|
|
46
|
+
MCP 2026-07-28 drops the `initialize` handshake. The spec calls that revision *modern*
|
|
47
|
+
and everything up to 2025-11-25 *legacy*. In the modern era:
|
|
48
|
+
|
|
49
|
+
- every request carries its version in `_meta["io.modelcontextprotocol/protocolVersion"]`;
|
|
50
|
+
- servers MUST answer `server/discover` (supported versions, capabilities, identity);
|
|
51
|
+
- every result carries `resultType: "complete"`, and list results add `ttlMs` and
|
|
52
|
+
`cacheScope`;
|
|
53
|
+
- an unsupported version gets error `-32022` with `data: {supported, requested}`.
|
|
54
|
+
|
|
55
|
+
Both servers are **dual-era over stdio**. A request that names its version in `_meta`
|
|
56
|
+
gets the modern shape; anything else gets the legacy shape, unchanged. A modern-only
|
|
57
|
+
server would fail every legacy client, and legacy clients cannot fall forward.
|
|
58
|
+
|
|
59
|
+
**Never echo the requested version.** Both servers used to answer `initialize` with
|
|
60
|
+
whatever version the client sent, including dates that do not exist. The client then
|
|
61
|
+
believes the server speaks a revision it has never heard of and waits for fields that
|
|
62
|
+
never arrive. The answer must come from a list the server implements. `initialize`
|
|
63
|
+
always selects the legacy era, so a client asking there for 2026-07-28 gets 2025-11-25.
|
|
64
|
+
That case is real: at least one client release proposed the modern version inside
|
|
65
|
+
`initialize`.
|
|
66
|
+
|
|
67
|
+
**How a dual-era client probes** (checked against Claude Code 2.1.284 through a logging
|
|
68
|
+
shim). By default it still sends `initialize`. With `MCP_PROTOCOL_NEGOTIATION=auto` it
|
|
69
|
+
sends `server/discover` first and falls back to `initialize` on any error that is not a
|
|
70
|
+
recognised modern one. So `-32601` on discover means "legacy server", and `-32022` means
|
|
71
|
+
"modern server, retry with a listed version". A server that cannot serve modern requests
|
|
72
|
+
must never return the second: a public MCP server that did had its client stop seeing
|
|
73
|
+
its tools.
|
|
74
|
+
|
|
75
|
+
**The HTTP transport is legacy-only** (`server.handle(m, modern=False)`). Modern
|
|
76
|
+
Streamable HTTP adds `Mcp-Method` / `Mcp-Name` header rules that `http_server.py` does
|
|
77
|
+
not implement, so over HTTP discover stays a plain `-32601`. Lift that only together
|
|
78
|
+
with the header rules.
|
|
79
|
+
|
|
80
|
+
**Not used, and deprecated in 2026-07-28 anyway:** roots, sampling, logging and dynamic
|
|
81
|
+
client registration. Nothing here should start depending on them.
|
|
82
|
+
|
|
83
|
+
**The tool-list digest.** `server/discover` reports `_meta["com.procesio/toolsDigest"]`:
|
|
84
|
+
sha256 over the canonical JSON of the `tools` array (keys sorted, no whitespace, UTF-8,
|
|
85
|
+
non-ASCII unescaped). The procesio-oss exporter writes the same value for the chat
|
|
86
|
+
surface into the public `server.json`, which the MCP Registry does not allow to change
|
|
87
|
+
after publication. The value a server reports about itself is a label for spotting the
|
|
88
|
+
release, not a control - the spec says self-reported server information must not drive
|
|
89
|
+
security decisions. The control is a client or gateway hashing the list it actually
|
|
90
|
+
received and comparing it with the registry copy. Changing the canonical form in one
|
|
91
|
+
place breaks every comparison, so `tests/test_pyoss_pins.py` asserts the exporter and
|
|
92
|
+
`protocol.py` agree.
|
|
93
|
+
|
|
94
|
+
## Capability discovery — why it is narrow
|
|
95
|
+
|
|
96
|
+
A big tool's full schema is not a large answer, it is NO answer. `procesio` alone is
|
|
97
|
+
~369 KB / 379 actions; an MCP client truncates that to a single-line JSON file, and
|
|
98
|
+
then `read` (offset/limit sees one line), `grep` (ripgrep refuses a record over 64 KB)
|
|
99
|
+
and `bash` (permission-gated) all fail on it. The turn is spent and the model has
|
|
100
|
+
nothing. Measured on real autonomous runs: **27% of all tool calls were the model
|
|
101
|
+
guessing argument names**, e.g. the same action retried with four different spellings
|
|
102
|
+
(`--name`, `--title`, `--datastore_name`, `--workspace_id`) when the manifest said
|
|
103
|
+
`--payload`.
|
|
104
|
+
|
|
105
|
+
So `capabilities` answers narrowest-first:
|
|
106
|
+
|
|
107
|
+
| call | returns | size (procesio) |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `{}` | compact tool/agent/skill list | small |
|
|
110
|
+
| `{search}` | matching ACTIONS, name+description only | ~0.3 KB |
|
|
111
|
+
| `{name, action}` | that action's args + the literal call shape | ~1–2 KB |
|
|
112
|
+
| `{name}` | full schema, **or** the action-name index if oversized | 11 KB (was 369 KB) |
|
|
113
|
+
|
|
114
|
+
Three rules that matter when touching this:
|
|
115
|
+
|
|
116
|
+
- **The degrade is a mechanism, not advice.** The prompt used to carry "NEVER call
|
|
117
|
+
`aat_capabilities` with a name"; transcripts show the model ignoring it and burning
|
|
118
|
+
the turn exactly as described above. Over `AAT_CAPABILITIES_MAX_BYTES` (default
|
|
119
|
+
40 000) the payload becomes the action index plus a pointer to `action=`/`search=`.
|
|
120
|
+
It keys off SIZE, not a tool list, so it covers every tool that grows.
|
|
121
|
+
- **Usage errors answer themselves** (`server._usage_help`). On `unknown action` /
|
|
122
|
+
`unrecognized arguments` / `arguments are required`, the failure carries a `schema`
|
|
123
|
+
field with the valid arg names, or `did_you_mean` for the action. The framework
|
|
124
|
+
already held the answer at that moment; it just never said it. One choke point,
|
|
125
|
+
every tool, no per-tool change. Remote errors (HTTP 4xx/5xx) are NOT enriched —
|
|
126
|
+
those are real feedback, not naming problems.
|
|
127
|
+
- **Suggestions must survive word order and plurals.** A model writes
|
|
128
|
+
`credential-list` for `list-credentials`; edit distance alone ranks those far apart,
|
|
129
|
+
so `_suggest` compares singularized WORD SETS first and only then falls back to
|
|
130
|
+
`difflib`.
|
|
131
|
+
|
|
132
|
+
Argument names are returned verbatim from the manifest (`workspace-id`, hyphenated).
|
|
133
|
+
Returning the literal spelling is what stops the snake_case guessing — do not
|
|
134
|
+
normalize or prettify them.
|
|
135
|
+
|
|
136
|
+
## Mechanics / gotchas
|
|
137
|
+
|
|
138
|
+
- **Naming:** the parent dir is `webplatform/`, NOT `platform/` — a top-level
|
|
139
|
+
`platform/` package shadows Python's stdlib `platform` module whenever repo root is
|
|
140
|
+
on `sys.path` (every framework subprocess), breaking keyring/pydantic. Do not rename
|
|
141
|
+
it back.
|
|
142
|
+
- **Execution reuse:** `bridge.run_tool/run_agent` delegate to
|
|
143
|
+
`dashboard.server.runner` (`flags_from` + `run_tool`/`run_agent`) — ONE definition of
|
|
144
|
+
"shell a framework script and normalize its JSON". `flags_from` JSON-encodes
|
|
145
|
+
dict/list arg values into a single argv element; the subprocess is a **list** (no
|
|
146
|
+
shell), which is why structured args don't need escaping.
|
|
147
|
+
- **Registry cost:** `aat_capabilities` (no name) calls `registry.list_tools/agents`,
|
|
148
|
+
which probes credential presence per secret — a few hundred ms. Fine for the low
|
|
149
|
+
call volume; cache if it ever matters.
|
|
150
|
+
- **Creds backend:** `registry` uses `tools/_lib/creds` (Windows Credential Manager
|
|
151
|
+
today). Running the server on another OS needs the creds backend from spec 06.
|
|
152
|
+
|
|
153
|
+
## Safety gate (spec 03)
|
|
154
|
+
|
|
155
|
+
- **Code-authoritative, pre-execution** (`gate.py` → `agents/_lib/reversibility`). The
|
|
156
|
+
plain `run_tool`/`run_agent` refuse an irreversible action (verb in the tool/agent
|
|
157
|
+
name or the ACTION name — send-message, delete-messages, issue-invoice) and return
|
|
158
|
+
`approval_required`; the `*_confirmed` tools execute it. Classification is on
|
|
159
|
+
name+action only, NOT arg values (a subject line "please send..." must not trip it).
|
|
160
|
+
- **opencode permission keys (namespaced `aat_*`):** `aat_run_tool`/`aat_run_agent` →
|
|
161
|
+
`allow` (the server code-gate refuses irreversible on them), `aat_run_tool_confirmed`
|
|
162
|
+
/`aat_run_agent_confirmed` → `ask` (the human approval), `aat_capabilities`/
|
|
163
|
+
`aat_get_skill` → `allow`. This is why the human gate is unforgeable: the model
|
|
164
|
+
can't self-approve the `ask`, and can't route an irreversible action through an
|
|
165
|
+
`allow` tool (it refuses).
|
|
166
|
+
- **Headless fail-safe:** `AAT_MCP_DENY_IRREVERSIBLE=1` makes even the confirmed tools
|
|
167
|
+
refuse — matches `orchestrator drive`'s default when no human is in the seat.
|
|
168
|
+
|
|
169
|
+
## Two surfaces over one substrate
|
|
170
|
+
|
|
171
|
+
There are two MCP servers here, on purpose. `server.py` offers six freeform tools that
|
|
172
|
+
dispatch whatever the registry holds - right for an operator driving the framework.
|
|
173
|
+
`chat_server.py` offers one named tool per operation, built from `chat_surface.yaml` -
|
|
174
|
+
what a general chat client and a directory review both need.
|
|
175
|
+
|
|
176
|
+
**A published tool list is a different kind of artefact from a registry.** The registry
|
|
177
|
+
is the source of truth for what a tool IS, and a surface that derives from it tracks it
|
|
178
|
+
automatically, which is correct for the freeform one. A published list is a contract
|
|
179
|
+
with people who did not write the manifests, and deriving it from them means a rename
|
|
180
|
+
silently removes a published tool, a new argument silently reshapes a published schema,
|
|
181
|
+
and a new tool silently appears in a surface someone reviewed. **MCP clients cache tool
|
|
182
|
+
definitions at initialisation and do not refresh them**, so none of those three errors
|
|
183
|
+
even produce an error - the client keeps calling the old shape and the model
|
|
184
|
+
misunderstands the result. That is why the declaration is a separate file and why the
|
|
185
|
+
disagreement is resolved at CI rather than at a user's call.
|
|
186
|
+
|
|
187
|
+
**`read_only` and `reversible` answer different questions.** Reversible asks whether a
|
|
188
|
+
change can be undone; read-only asks whether anything changes at all. A create action is
|
|
189
|
+
reversible and is not read-only. Mapping one onto the other would mark every write
|
|
190
|
+
safe to run unattended. The implication only runs one way, and that is what is asserted:
|
|
191
|
+
read_only ⟹ reversible.
|
|
192
|
+
|
|
193
|
+
**Annotations are not a control.** The spec tells clients to treat tool annotations as
|
|
194
|
+
untrusted. They drive a client's auto-run behaviour, so a wrong one is a write that
|
|
195
|
+
fires unprompted - worth getting right - but the enforcement is `gate.py`. The curated
|
|
196
|
+
surface carries no `*_confirmed` twin and instead refuses irreversible actions outright,
|
|
197
|
+
with a test asserting nothing declared is irreversible; adding a destructive operation
|
|
198
|
+
fails the build rather than growing a second, softer approval path.
|
|
199
|
+
|
|
200
|
+
**Shared protocol, separate surfaces.** The two servers differ in what they publish and
|
|
201
|
+
to whom, so their tools, dispatchers and identities stay apart. The protocol is a
|
|
202
|
+
different matter: it has one correct behaviour. It used to be duplicated, about 50 lines
|
|
203
|
+
in each server, and the two copies made the same mistake - agreeing to any version a
|
|
204
|
+
client named. It now lives once in `protocol.py`: negotiation, the modern and legacy
|
|
205
|
+
result shapes, `server/discover` and the stdio loop. That module is standard library
|
|
206
|
+
only and imports neither surface, so a change to one surface cannot reach the other
|
|
207
|
+
through it. Both servers import `bridge`, `gate` and `protocol`; neither imports the
|
|
208
|
+
other. `test_chat_surface.py` asserts all of this by parsing the AST.
|
|
209
|
+
|
|
210
|
+
### Design rules taken from published guidance
|
|
211
|
+
|
|
212
|
+
- **Namespace tool names by domain** (`procesio_list_processes`, not `list_processes`).
|
|
213
|
+
A directory client merges several servers into one list. Anthropic's tool-writing
|
|
214
|
+
guidance reports that naming scheme alone has non-trivial effects on tool-use
|
|
215
|
+
evaluations.
|
|
216
|
+
- **Curate for workflows, not endpoints.** Prefer `search_*` over `list_*` because agent
|
|
217
|
+
context is limited. The generated REST passthroughs are exactly what does not belong
|
|
218
|
+
in a published surface.
|
|
219
|
+
- **Cap tool results.** A result lands directly in a model's context, so an unbounded
|
|
220
|
+
one is a context leak rather than a large answer. Truncation carries a hint naming the
|
|
221
|
+
arguments that narrow *that* tool, because a generic "too large" is not actionable.
|
|
222
|
+
(Claude Code caps tool responses at 25,000 tokens by default; MCP metadata has been
|
|
223
|
+
measured at ~40% of token usage in some environments, which is the argument for a
|
|
224
|
+
small surface.)
|
|
225
|
+
- **Version the surface separately from the package.** The MCP registry requires a
|
|
226
|
+
unique version string per publication and recommends semver; `server.json` aligns with
|
|
227
|
+
the release, while `surface_version` describes the published tool contract. A client
|
|
228
|
+
pins to a surface, and a release can ship with the surface unchanged.
|
|
229
|
+
- **Known gap:** the declaration is a 1:1 mapping (one MCP tool = one action), which
|
|
230
|
+
keeps it free of behaviour and fully verifiable against the registry, but forecloses
|
|
231
|
+
the consolidation that guidance recommends (one `schedule_event` rather than find-slot
|
|
232
|
+
+ book). Consolidation needs composition logic in the surface layer and its own tests.
|
|
233
|
+
|
|
234
|
+
## Status
|
|
235
|
+
|
|
236
|
+
Spec 02 (B1) transport + surface AND spec 03 (B2) reversibility gate: built +
|
|
237
|
+
unit-tested (19 tests) + wire-tested (send refused on plain tool, executes on
|
|
238
|
+
confirmed). Tool names dropped the `aat_` prefix (opencode re-adds it → clean
|
|
239
|
+
`aat_run_tool`). Pending: live opencode action-count/gate check in the browser, and
|
|
240
|
+
HTTP transport (spec 05).
|
|
241
|
+
|
|
242
|
+
Dual-era negotiation for MCP 2026-07-28 (`protocol.py`): built, unit-tested
|
|
243
|
+
(`tests/test_protocol.py`), and checked live with Claude Code in both negotiation modes
|
|
244
|
+
(default `initialize`, and `MCP_PROTOCOL_NEGOTIATION=auto` via `server/discover`).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# aat-mcp — the AAT → MCP bridge
|
|
2
|
+
|
|
3
|
+
A stdio MCP server that exposes the live AAT registry to any MCP client (opencode
|
|
4
|
+
now, others later) as a **small generic surface**. It replaces bash passthrough:
|
|
5
|
+
capabilities are called as typed tools with **structured JSON args** (no shell
|
|
6
|
+
quote-escaping), and capability schemas replace `--help` spelunking.
|
|
7
|
+
|
|
8
|
+
Part of the "local web platform" initiative — specs `todo/local web platform Claude replacer/02-aat-mcp-bridge.md` (transport) and `03-safety-approval-parity.md` (gate).
|
|
9
|
+
|
|
10
|
+
## Tools exposed
|
|
11
|
+
|
|
12
|
+
Server tool names below; opencode shows them prefixed with the server name (e.g.
|
|
13
|
+
`run_tool` → `aat_run_tool`).
|
|
14
|
+
|
|
15
|
+
| MCP tool | Args | Purpose |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `capabilities` | `{kind?, name?, action?, search?}` | discovery, narrowest door first (the `--help` replacement). Nothing: compact list of every ready tool/agent/skill. `search`: matching actions across everything (or inside `name`). `name`+`action`: that one action's arg schema. `name` alone: the full schema, degraded to the action-name index when oversized — see AAT-MCP-NOTES.md |
|
|
18
|
+
| `run_tool` | `{tool, action?, args?}` | run a **reversible** tool action; refuses irreversible ones with `approval_required` |
|
|
19
|
+
| `run_agent` | `{agent, action?, args?}` | run a **reversible** agent action |
|
|
20
|
+
| `run_tool_confirmed` | `{tool, action?, args?}` | run a tool **including irreversible** actions — opencode asks the operator to approve |
|
|
21
|
+
| `run_agent_confirmed` | `{agent, action?, args?}` | run an agent including irreversible actions — operator-approved |
|
|
22
|
+
| `get_skill` | `{name}` | the skill's full markdown (model-decided loading; spec 04) |
|
|
23
|
+
|
|
24
|
+
`args` is a JSON object of flag name → value. dict/array values are JSON-encoded into
|
|
25
|
+
a single argv element and passed via a subprocess **list** (no shell) — the fix for
|
|
26
|
+
the B0 spike's quote-escaping thrash.
|
|
27
|
+
|
|
28
|
+
## Safety gate (code-authoritative)
|
|
29
|
+
|
|
30
|
+
The reversibility gate is **code, evaluated before execution** (`gate.py` →
|
|
31
|
+
`agents/_lib/reversibility`, the same policy as `orchestrator drive` and `deputy`):
|
|
32
|
+
|
|
33
|
+
- `run_tool`/`run_agent` **refuse** an irreversible action (send/delete/pay/post/
|
|
34
|
+
issue-invoice/...) and return `approval_required`, naming the `*_confirmed` path.
|
|
35
|
+
- Only the `*_confirmed` tools are marked `ask` in opencode, so a **human** approves
|
|
36
|
+
each side effect. A model cannot forge the approval, and cannot bypass by picking
|
|
37
|
+
the plain tool (it refuses). Reversible/read actions run freely on the plain tools.
|
|
38
|
+
- `AAT_MCP_DENY_IRREVERSIBLE=1` makes even the confirmed tools refuse — a fail-safe
|
|
39
|
+
for a headless run with no human in the seat.
|
|
40
|
+
|
|
41
|
+
## Run
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
python webplatform/aat_mcp/server.py # opencode spawns this over stdio
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Quick manual check (newline-delimited JSON-RPC on stdin):
|
|
48
|
+
```
|
|
49
|
+
printf '%s\n' \
|
|
50
|
+
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}' \
|
|
51
|
+
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
|
|
52
|
+
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run_tool","arguments":{"tool":"hello-world","args":{"name":"MCP"}}}}' \
|
|
53
|
+
| .venv/Scripts/python.exe webplatform/aat_mcp/server.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Design
|
|
57
|
+
|
|
58
|
+
- **Placement:** a platform component (`webplatform/aat_mcp/`), not a registered tool
|
|
59
|
+
— a long-running server does not fit the JSON-in/out-and-exit tool contract, and
|
|
60
|
+
this avoids a tools→agents import inversion (execution reuses `dashboard.server.runner`).
|
|
61
|
+
- **Generic, not exploded:** a handful of tools, not one-per-capability — avoids MCP
|
|
62
|
+
tool-count limits and manifest drift. The model discovers capabilities via
|
|
63
|
+
`capabilities` (the router map), exactly as a session does today.
|
|
64
|
+
- **Source of truth:** capability + arg schemas are read live from the registry
|
|
65
|
+
(manifests); the reversibility policy is the shared `agents/_lib/reversibility`.
|
|
66
|
+
- **No new dependency:** the MCP protocol is hand-rolled JSON-RPC over stdio (stdlib
|
|
67
|
+
only), robust to environment quirks.
|
|
68
|
+
|
|
69
|
+
## Not yet (downstream specs)
|
|
70
|
+
|
|
71
|
+
- **HTTP/SSE transport** (spec 05): for containers/k8s, where opencode connects as a
|
|
72
|
+
remote MCP client. stdio is the local transport.
|
|
73
|
+
|
|
74
|
+
## Tests
|
|
75
|
+
|
|
76
|
+
`python -m pytest webplatform/aat_mcp/tests/ -q` — protocol dispatch, the
|
|
77
|
+
reversibility gate (refuse/confirm/headless-deny), and the anti-thrash argv
|
|
78
|
+
guarantee, all with fakes (no real subprocess or credentials).
|