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,202 @@
|
|
|
1
|
+
"""Generate a per-tool SKILL.md - the agent's instruction manual - from tool.yaml.
|
|
2
|
+
|
|
3
|
+
WHY
|
|
4
|
+
---
|
|
5
|
+
Borrowed from CLI-Anything, which ships a generated `SKILL.md` beside every CLI so
|
|
6
|
+
an agent can read how to drive it. We had no equivalent: a tool advertises itself
|
|
7
|
+
through one hand-written line in the Capability Router plus a README written for
|
|
8
|
+
humans. That line is enough to CHOOSE a tool and not enough to USE one - the agent
|
|
9
|
+
then falls back to `--help`, which for a big tool costs more context than the task.
|
|
10
|
+
|
|
11
|
+
The point of generating it is drift: a hand-written manual goes stale the first
|
|
12
|
+
time an action is added, and a stale manual is worse than none because the agent
|
|
13
|
+
trusts it. This one is derived from the manifest, which is already the source of
|
|
14
|
+
truth (Hard rule 3), so it cannot disagree with the code.
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
python scripts/build-tool-skill.py <tool> [--out PATH] [--stdout] [--check]
|
|
18
|
+
|
|
19
|
+
--check exits 1 if the file on disk differs from what would be generated, so CI
|
|
20
|
+
or a test can fail on a stale skill instead of shipping one.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
import yaml
|
|
29
|
+
|
|
30
|
+
REPO = Path(__file__).resolve().parents[1]
|
|
31
|
+
if str(REPO) not in sys.path:
|
|
32
|
+
sys.path.insert(0, str(REPO))
|
|
33
|
+
|
|
34
|
+
from tools._lib import manifest as M # noqa: E402
|
|
35
|
+
|
|
36
|
+
MAX_DESC = 160
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _group_of(action_name: str) -> str:
|
|
40
|
+
return action_name.split("-", 1)[0]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _one_line(text: str, limit: int = MAX_DESC) -> str:
|
|
44
|
+
"""First sentence, collapsed - an agent scanning a table needs the verb, not
|
|
45
|
+
the essay. The full description stays in the manifest."""
|
|
46
|
+
flat = " ".join((text or "").split())
|
|
47
|
+
if len(flat) <= limit:
|
|
48
|
+
return flat
|
|
49
|
+
cut = flat[:limit].rsplit(" ", 1)[0]
|
|
50
|
+
return cut + "…"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _required_args(action) -> list[str]:
|
|
54
|
+
return [a.name for a in action.args if getattr(a, "required", False)]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _frontmatter(name: str, description: str) -> str:
|
|
58
|
+
"""The YAML frontmatter block, emitted through the dumper.
|
|
59
|
+
|
|
60
|
+
NOT an f-string. A manifest description is arbitrary prose and routinely
|
|
61
|
+
contains a colon followed by a space ("full coverage of the Web API: every
|
|
62
|
+
endpoint is an action"). In a plain YAML scalar that sequence starts a nested
|
|
63
|
+
mapping, so the document fails to parse and the file stops being a loadable
|
|
64
|
+
skill - silently, because nothing here reads it back. It held for 36 of 75
|
|
65
|
+
tools, and the ones it hit were the well-described ones, since description
|
|
66
|
+
length correlates with punctuation.
|
|
67
|
+
|
|
68
|
+
Dumping guarantees the round-trip: whatever punctuation a description carries,
|
|
69
|
+
yaml.safe_load returns it. width is set high so a long description stays on one
|
|
70
|
+
line rather than being folded, which keeps the diff readable.
|
|
71
|
+
"""
|
|
72
|
+
block = yaml.safe_dump(
|
|
73
|
+
{"name": name, "description": description},
|
|
74
|
+
sort_keys=False, allow_unicode=True, width=10 ** 9,
|
|
75
|
+
default_flow_style=False,
|
|
76
|
+
).rstrip("\n")
|
|
77
|
+
return f"---\n{block}\n---"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def render(tool: M.ToolManifest) -> str:
|
|
81
|
+
"""The SKILL.md body. Frontmatter first so a skill loader can index it."""
|
|
82
|
+
actions = list(tool.actions)
|
|
83
|
+
groups: dict[str, list] = {}
|
|
84
|
+
for a in actions:
|
|
85
|
+
groups.setdefault(_group_of(a.name), []).append(a)
|
|
86
|
+
grouped = len(groups) > 1 and len(actions) > 12
|
|
87
|
+
|
|
88
|
+
routing = tool.routing
|
|
89
|
+
primary = getattr(routing, "primary_action", None) if routing else None
|
|
90
|
+
example = getattr(routing, "example", None) if routing else None
|
|
91
|
+
|
|
92
|
+
out: list[str] = []
|
|
93
|
+
out.append(_frontmatter(tool.name, _one_line(tool.description, 400)))
|
|
94
|
+
out.append("")
|
|
95
|
+
out.append(f"# {tool.name}")
|
|
96
|
+
out.append("")
|
|
97
|
+
out.append(" ".join((tool.description or "").split()))
|
|
98
|
+
out.append("")
|
|
99
|
+
|
|
100
|
+
out.append("## How to call it")
|
|
101
|
+
out.append("")
|
|
102
|
+
out.append("```bash")
|
|
103
|
+
out.append(f"python scripts/run-tool.py {tool.name} <action> [--args]")
|
|
104
|
+
if example:
|
|
105
|
+
out.append(f"# e.g. {example}")
|
|
106
|
+
out.append("```")
|
|
107
|
+
out.append("")
|
|
108
|
+
out.append("One JSON object on stdout for success; `{\"error\": {\"code\", "
|
|
109
|
+
"\"message\", \"details\"}}` and a non-zero exit on failure. "
|
|
110
|
+
"Progress and logs go to stderr only.")
|
|
111
|
+
out.append("")
|
|
112
|
+
if primary:
|
|
113
|
+
out.append(f"**Start with `{primary}`.**")
|
|
114
|
+
out.append("")
|
|
115
|
+
|
|
116
|
+
if tool.secrets:
|
|
117
|
+
out.append("## Credentials")
|
|
118
|
+
out.append("")
|
|
119
|
+
out.append("Stored in the OS credential store, never in files. Missing ones "
|
|
120
|
+
"are reported by `python scripts/list-tools.py`.")
|
|
121
|
+
out.append("")
|
|
122
|
+
for s in tool.secrets:
|
|
123
|
+
out.append(f"- `agents-and-tools:{tool.name}:{s.name}`"
|
|
124
|
+
+ (f" — {_one_line(s.description)}" if s.description else ""))
|
|
125
|
+
out.append("")
|
|
126
|
+
|
|
127
|
+
out.append("## Actions")
|
|
128
|
+
out.append("")
|
|
129
|
+
if grouped:
|
|
130
|
+
for group in sorted(groups):
|
|
131
|
+
out.append(f"### {group}")
|
|
132
|
+
out.append("")
|
|
133
|
+
out.append("| action | required args | what it does |")
|
|
134
|
+
out.append("|---|---|---|")
|
|
135
|
+
for a in sorted(groups[group], key=lambda x: x.name):
|
|
136
|
+
req = ", ".join(f"`--{n}`" for n in _required_args(a)) or "—"
|
|
137
|
+
out.append(f"| `{a.name}` | {req} | {_one_line(a.description)} |")
|
|
138
|
+
out.append("")
|
|
139
|
+
else:
|
|
140
|
+
out.append("| action | required args | what it does |")
|
|
141
|
+
out.append("|---|---|---|")
|
|
142
|
+
for a in sorted(actions, key=lambda x: x.name):
|
|
143
|
+
req = ", ".join(f"`--{n}`" for n in _required_args(a)) or "—"
|
|
144
|
+
out.append(f"| `{a.name}` | {req} | {_one_line(a.description)} |")
|
|
145
|
+
out.append("")
|
|
146
|
+
|
|
147
|
+
out.append("---")
|
|
148
|
+
out.append("")
|
|
149
|
+
out.append(f"Generated from `tools/{tool.name}/tool.yaml` by "
|
|
150
|
+
"`scripts/build-tool-skill.py`. Do not edit by hand — change the "
|
|
151
|
+
"manifest and regenerate.")
|
|
152
|
+
out.append("")
|
|
153
|
+
return "\n".join(out)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def main() -> None:
|
|
157
|
+
p = argparse.ArgumentParser(description=__doc__)
|
|
158
|
+
p.add_argument("tool", help="tool name as it appears in list-tools")
|
|
159
|
+
p.add_argument("--out", help="output path (default: tools/<tool>/SKILL.md)")
|
|
160
|
+
p.add_argument("--stdout", action="store_true", help="print instead of writing")
|
|
161
|
+
p.add_argument("--check", action="store_true",
|
|
162
|
+
help="exit 1 if the file on disk is stale")
|
|
163
|
+
args = p.parse_args()
|
|
164
|
+
|
|
165
|
+
# Load by directory, skipping siblings that fail to parse: one broken manifest
|
|
166
|
+
# elsewhere in tools/ must not stop us generating this tool's skill.
|
|
167
|
+
tools: dict[str, M.ToolManifest] = {}
|
|
168
|
+
for manifest_path in sorted((REPO / "tools").glob("*/tool.yaml")):
|
|
169
|
+
if manifest_path.parent.name.startswith("_"):
|
|
170
|
+
continue
|
|
171
|
+
try:
|
|
172
|
+
m = M.load_tool(manifest_path)
|
|
173
|
+
except Exception as exc: # noqa: BLE001
|
|
174
|
+
if manifest_path.parent.name == args.tool:
|
|
175
|
+
sys.exit(f"{args.tool}: manifest failed to load: {exc}")
|
|
176
|
+
continue
|
|
177
|
+
tools[m.name] = m
|
|
178
|
+
if args.tool not in tools:
|
|
179
|
+
sys.exit(f"unknown tool: {args.tool}. Known: {', '.join(sorted(tools))}")
|
|
180
|
+
tool = tools[args.tool]
|
|
181
|
+
body = render(tool)
|
|
182
|
+
|
|
183
|
+
if args.stdout:
|
|
184
|
+
print(body)
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
# Write beside the manifest, NOT at tools/<name>/: a manifest name and its
|
|
188
|
+
# directory can differ (tools/google_mail/ declares name google-mail), so
|
|
189
|
+
# deriving the path from the name misses every such tool.
|
|
190
|
+
dest = Path(args.out) if args.out else (tool.path / "SKILL.md")
|
|
191
|
+
if args.check:
|
|
192
|
+
current = dest.read_text(encoding="utf-8") if dest.exists() else ""
|
|
193
|
+
if current != body:
|
|
194
|
+
sys.exit(f"STALE: {dest} differs from the manifest. Regenerate it.")
|
|
195
|
+
print(f"up to date: {dest}")
|
|
196
|
+
return
|
|
197
|
+
dest.write_text(body, encoding="utf-8", newline="\n")
|
|
198
|
+
print(f"wrote {dest} ({len(body)} bytes, {len(tool.actions)} actions)")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
if __name__ == "__main__":
|
|
202
|
+
main()
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Check the machine-level prerequisites every tool declares in `requires:`.
|
|
2
|
+
|
|
3
|
+
`uv sync` builds the venv. It does not install a browser engine, a database driver
|
|
4
|
+
or a codec — and because those are imported lazily, a machine missing them still
|
|
5
|
+
reports every tool "ready" and passes the whole test suite. The failure surfaces
|
|
6
|
+
at the user's first real call, one tool at a time.
|
|
7
|
+
|
|
8
|
+
This runs each requirement's `check` command and says what is actually missing,
|
|
9
|
+
so a fresh install can be verified in one command instead of by incident.
|
|
10
|
+
|
|
11
|
+
python scripts/check-requirements.py # everything, grouped
|
|
12
|
+
python scripts/check-requirements.py --tool web
|
|
13
|
+
python scripts/check-requirements.py --json
|
|
14
|
+
python scripts/check-requirements.py --quiet # only what's missing
|
|
15
|
+
|
|
16
|
+
Exit code: 0 if nothing REQUIRED is missing (self-installing ones are warnings),
|
|
17
|
+
1 otherwise — so it can gate an onboarding run.
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
import subprocess
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
REPO = Path(__file__).resolve().parents[1]
|
|
28
|
+
if str(REPO) not in sys.path:
|
|
29
|
+
sys.path.insert(0, str(REPO))
|
|
30
|
+
|
|
31
|
+
from tools._lib import manifest as M # noqa: E402
|
|
32
|
+
|
|
33
|
+
TIMEOUT = 120
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _probe(cmd: str) -> tuple[bool, str]:
|
|
37
|
+
"""Run a check command. Present == exit 0. Never raises.
|
|
38
|
+
|
|
39
|
+
`{python}` in a check is replaced with THIS interpreter. A check must not
|
|
40
|
+
depend on how the shell was started: writing `uv run python -c ...` reported
|
|
41
|
+
Playwright's browser missing on a machine that had it, because `uv` was not on
|
|
42
|
+
PATH in that context - a false alarm is as bad as a missed one."""
|
|
43
|
+
if not cmd:
|
|
44
|
+
return True, "no check declared"
|
|
45
|
+
cmd = cmd.replace("{python}", f'"{sys.executable}"')
|
|
46
|
+
try:
|
|
47
|
+
p = subprocess.run(cmd, shell=True, cwd=REPO, capture_output=True,
|
|
48
|
+
text=True, encoding="utf-8", errors="replace",
|
|
49
|
+
timeout=TIMEOUT)
|
|
50
|
+
except subprocess.TimeoutExpired:
|
|
51
|
+
return False, f"check timed out after {TIMEOUT}s"
|
|
52
|
+
except Exception as exc: # noqa: BLE001
|
|
53
|
+
return False, f"check could not run: {exc}"
|
|
54
|
+
if p.returncode == 0:
|
|
55
|
+
return True, ""
|
|
56
|
+
tail = ((p.stderr or p.stdout) or "").strip().splitlines()
|
|
57
|
+
return False, (tail[-1][:160] if tail else f"exit {p.returncode}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def collect(only: str | None = None) -> list[dict]:
|
|
61
|
+
"""One row per (tool, requirement). Requirements are deduplicated per NAME
|
|
62
|
+
when probing: chromium is the same chromium for all twelve tools that need
|
|
63
|
+
it, and probing it twelve times just makes the run slow."""
|
|
64
|
+
rows: list[dict] = []
|
|
65
|
+
cache: dict[str, tuple[bool, str]] = {}
|
|
66
|
+
for mp in sorted((REPO / "tools").glob("*/tool.yaml")):
|
|
67
|
+
if mp.parent.name.startswith("_"):
|
|
68
|
+
continue
|
|
69
|
+
try:
|
|
70
|
+
tool = M.load_tool(mp)
|
|
71
|
+
except Exception: # noqa: BLE001 - a broken manifest is list-tools' problem
|
|
72
|
+
continue
|
|
73
|
+
if only and tool.name != only:
|
|
74
|
+
continue
|
|
75
|
+
for req in tool.requires:
|
|
76
|
+
if req.name not in cache:
|
|
77
|
+
cache[req.name] = _probe(req.check)
|
|
78
|
+
present, detail = cache[req.name]
|
|
79
|
+
rows.append({
|
|
80
|
+
"tool": tool.name, "requirement": req.name, "kind": req.kind,
|
|
81
|
+
"present": present, "auto": req.auto, "detail": detail,
|
|
82
|
+
"why": req.why.strip(), "install": req.install,
|
|
83
|
+
})
|
|
84
|
+
return rows
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def main() -> None:
|
|
88
|
+
p = argparse.ArgumentParser(description=__doc__)
|
|
89
|
+
p.add_argument("--tool", help="check one tool only")
|
|
90
|
+
p.add_argument("--json", action="store_true", dest="as_json")
|
|
91
|
+
p.add_argument("--quiet", action="store_true", help="only report what's missing")
|
|
92
|
+
args = p.parse_args()
|
|
93
|
+
|
|
94
|
+
rows = collect(args.tool)
|
|
95
|
+
if args.as_json:
|
|
96
|
+
print(json.dumps({"requirements": rows}, indent=1))
|
|
97
|
+
missing = [r for r in rows if not r["present"]]
|
|
98
|
+
blocking = [r for r in missing if not r["auto"]]
|
|
99
|
+
|
|
100
|
+
if not args.as_json:
|
|
101
|
+
by_req: dict[str, list[dict]] = {}
|
|
102
|
+
for r in rows:
|
|
103
|
+
by_req.setdefault(r["requirement"], []).append(r)
|
|
104
|
+
for name, group in sorted(by_req.items()):
|
|
105
|
+
first = group[0]
|
|
106
|
+
if first["present"] and args.quiet:
|
|
107
|
+
continue
|
|
108
|
+
mark = "OK " if first["present"] else ("WARN" if first["auto"] else "MISS")
|
|
109
|
+
tools = ", ".join(sorted({g["tool"] for g in group}))
|
|
110
|
+
print(f"[{mark}] {name} ({first['kind']}) — needed by {len(set(t['tool'] for t in group))} tool(s)")
|
|
111
|
+
print(f" {tools}")
|
|
112
|
+
if not first["present"]:
|
|
113
|
+
if first["detail"]:
|
|
114
|
+
print(f" check said: {first['detail']}")
|
|
115
|
+
if first["why"]:
|
|
116
|
+
print(f" why: {' '.join(first['why'].split())}")
|
|
117
|
+
if first["install"]:
|
|
118
|
+
print(f" install: {first['install']}")
|
|
119
|
+
if first["auto"]:
|
|
120
|
+
print(" (self-installing on first use — warning, not a blocker)")
|
|
121
|
+
print()
|
|
122
|
+
if not missing:
|
|
123
|
+
print("All declared machine requirements are present.")
|
|
124
|
+
elif blocking:
|
|
125
|
+
print(f"{len(blocking)} blocking requirement(s) missing.")
|
|
126
|
+
|
|
127
|
+
sys.exit(1 if blocking else 0)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
main()
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check skill ownership, freshness metadata, evaluation links, and release state."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from datetime import date
|
|
9
|
+
from pathlib import Path, PurePosixPath
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
13
|
+
if str(ROOT) not in sys.path:
|
|
14
|
+
sys.path.insert(0, str(ROOT))
|
|
15
|
+
|
|
16
|
+
from tools._lib.manifest import load_skill # noqa: E402
|
|
17
|
+
from tools._lib.skill_release import check_release_binding # noqa: E402
|
|
18
|
+
|
|
19
|
+
DEFAULT_SKILLS = ROOT / "skills"
|
|
20
|
+
DEFAULT_STATUS = DEFAULT_SKILLS / "evals" / "gates.json"
|
|
21
|
+
EXPECTED_GATES = set(range(7))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def check_skills(skills_root: Path, *, max_age_days: int | None = None,
|
|
25
|
+
today: date | None = None) -> list[dict[str, str]]:
|
|
26
|
+
findings: list[dict[str, str]] = []
|
|
27
|
+
now = today or date.today()
|
|
28
|
+
paths = sorted(skills_root.glob("*/SKILL.md"))
|
|
29
|
+
if not paths:
|
|
30
|
+
return [{"skill": "<repository>", "code": "no-skills", "message": "no skills found"}]
|
|
31
|
+
for skill_md in paths:
|
|
32
|
+
if skill_md.parent.name.startswith("_") or skill_md.parent.name == "tests":
|
|
33
|
+
continue
|
|
34
|
+
try:
|
|
35
|
+
manifest = load_skill(skill_md)
|
|
36
|
+
except Exception as exc: # noqa: BLE001
|
|
37
|
+
findings.append({"skill": skill_md.parent.name, "code": "invalid-skill",
|
|
38
|
+
"message": str(exc)})
|
|
39
|
+
continue
|
|
40
|
+
# Governance is opt-in via `source_policy`. A repo like procesio-cli whose
|
|
41
|
+
# skills/ IS the portfolio governs every skill; a framework like AAT also
|
|
42
|
+
# hosts imported/portable skills that never signed up for owner/freshness/
|
|
43
|
+
# eval-suite discipline, and forcing that metadata on them would be wrong.
|
|
44
|
+
if not manifest.source_policy:
|
|
45
|
+
continue
|
|
46
|
+
required = {
|
|
47
|
+
"owner": manifest.owner,
|
|
48
|
+
"last_verified": manifest.last_verified,
|
|
49
|
+
"baseline_version": manifest.baseline_version,
|
|
50
|
+
"eval_suite": manifest.eval_suite,
|
|
51
|
+
"source_policy": manifest.source_policy,
|
|
52
|
+
}
|
|
53
|
+
for field, value in required.items():
|
|
54
|
+
if not value:
|
|
55
|
+
findings.append({
|
|
56
|
+
"skill": manifest.name,
|
|
57
|
+
"code": f"missing-{field.replace('_', '-')}",
|
|
58
|
+
"message": f"{field} is required for published skills",
|
|
59
|
+
})
|
|
60
|
+
if not manifest.routing or not manifest.routing.triggers:
|
|
61
|
+
findings.append({"skill": manifest.name, "code": "missing-routing",
|
|
62
|
+
"message": "curated routing triggers are required"})
|
|
63
|
+
if (max_age_days is not None and manifest.source_policy == "timestamped"
|
|
64
|
+
and manifest.last_verified is not None):
|
|
65
|
+
age = (now - manifest.last_verified).days
|
|
66
|
+
if age < 0:
|
|
67
|
+
findings.append({"skill": manifest.name, "code": "future-verification-date",
|
|
68
|
+
"message": f"last_verified is {abs(age)} days in the future"})
|
|
69
|
+
elif age > max_age_days:
|
|
70
|
+
findings.append({"skill": manifest.name, "code": "stale-timestamped-skill",
|
|
71
|
+
"message": f"last verified {age} days ago; maximum is {max_age_days}"})
|
|
72
|
+
return findings
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def check_status(path: Path, *, require_release_eligible: bool = False,
|
|
76
|
+
verify_snapshot: bool = False, skills_root: Path = DEFAULT_SKILLS,
|
|
77
|
+
repo_root: Path = ROOT) -> list[dict[str, str]]:
|
|
78
|
+
findings: list[dict[str, str]] = []
|
|
79
|
+
try:
|
|
80
|
+
raw: Any = json.loads(path.read_text(encoding="utf-8"))
|
|
81
|
+
except (OSError, ValueError) as exc:
|
|
82
|
+
return [{"skill": "<repository>", "code": "invalid-gate-status", "message": str(exc)}]
|
|
83
|
+
rows = raw.get("gates") if isinstance(raw, dict) else None
|
|
84
|
+
if not isinstance(rows, list):
|
|
85
|
+
return [{"skill": "<repository>", "code": "invalid-gate-status",
|
|
86
|
+
"message": "gates must be a list"}]
|
|
87
|
+
ids = [row.get("id") for row in rows if isinstance(row, dict)]
|
|
88
|
+
if (len(rows) != 7 or len(ids) != 7 or any(type(value) is not int for value in ids)
|
|
89
|
+
or set(ids) != EXPECTED_GATES):
|
|
90
|
+
return [{"skill": "<repository>", "code": "incomplete-gate-set",
|
|
91
|
+
"message": "gate ids must be unique integers 0 through 6"}]
|
|
92
|
+
if (type(raw.get("release_eligible")) is not bool
|
|
93
|
+
or not isinstance(raw.get("release_blockers"), list)
|
|
94
|
+
or not all(isinstance(item, str) for item in raw["release_blockers"])):
|
|
95
|
+
return [{"skill": "<repository>", "code": "invalid-gate-status",
|
|
96
|
+
"message": "release_eligible must be Boolean and release_blockers a string list"}]
|
|
97
|
+
allowed = {"passed", "pending-external-run", "infrastructure-complete", "blocked"}
|
|
98
|
+
for row in rows:
|
|
99
|
+
if not isinstance(row, dict):
|
|
100
|
+
continue
|
|
101
|
+
if not isinstance(row.get("status"), str) or row["status"] not in allowed:
|
|
102
|
+
findings.append({"skill": "<repository>", "code": "invalid-gate-state",
|
|
103
|
+
"message": f"gate {row['id']} has an invalid status"})
|
|
104
|
+
evidence_paths = row.get("evidence", [])
|
|
105
|
+
if not isinstance(evidence_paths, list) or not all(isinstance(item, str) for item in evidence_paths):
|
|
106
|
+
findings.append({"skill": "<repository>", "code": "invalid-gate-evidence",
|
|
107
|
+
"message": "gate evidence must be a list of repository-relative paths"})
|
|
108
|
+
continue
|
|
109
|
+
for evidence in evidence_paths:
|
|
110
|
+
rel = PurePosixPath(evidence.replace("\\", "/"))
|
|
111
|
+
target = repo_root / evidence
|
|
112
|
+
try:
|
|
113
|
+
if (not evidence or "\x00" in evidence or len(evidence) > 4096
|
|
114
|
+
or rel.is_absolute() or ".." in rel.parts
|
|
115
|
+
or not target.resolve().is_relative_to(repo_root.resolve())):
|
|
116
|
+
raise ValueError("unsafe evidence path")
|
|
117
|
+
if not target.is_file():
|
|
118
|
+
findings.append({"skill": "<repository>", "code": "missing-gate-evidence",
|
|
119
|
+
"message": f"gate {row['id']} evidence file is missing"})
|
|
120
|
+
except (OSError, ValueError, RuntimeError):
|
|
121
|
+
findings.append({"skill": "<repository>", "code": "unsafe-gate-evidence",
|
|
122
|
+
"message": "gate evidence path is unsafe or unreadable"})
|
|
123
|
+
eligible = raw["release_eligible"]
|
|
124
|
+
blockers = raw.get("release_blockers") or []
|
|
125
|
+
all_passed = len(rows) == 7 and all(
|
|
126
|
+
isinstance(row, dict) and row.get("status") == "passed" for row in rows
|
|
127
|
+
)
|
|
128
|
+
if eligible and (not all_passed or blockers):
|
|
129
|
+
findings.append({"skill": "<repository>", "code": "false-release-eligibility",
|
|
130
|
+
"message": "release_eligible requires every gate passed and no blockers"})
|
|
131
|
+
if eligible or require_release_eligible or verify_snapshot:
|
|
132
|
+
gate5 = next(row for row in rows if row["id"] == 5)
|
|
133
|
+
findings += check_release_binding(
|
|
134
|
+
repo_root, skills_root, gate5.get("evaluated_candidate_commit"),
|
|
135
|
+
gate5.get("evaluated_candidate_fingerprint"),
|
|
136
|
+
)
|
|
137
|
+
if require_release_eligible and not eligible:
|
|
138
|
+
findings.append({"skill": "<repository>", "code": "release-blocked",
|
|
139
|
+
"message": "; ".join(str(item) for item in blockers) or "release not eligible"})
|
|
140
|
+
return findings
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def main(argv: list[str] | None = None) -> int:
|
|
144
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
145
|
+
parser.add_argument("--skills-root", type=Path, default=DEFAULT_SKILLS)
|
|
146
|
+
parser.add_argument("--status-file", type=Path, default=DEFAULT_STATUS)
|
|
147
|
+
parser.add_argument("--max-age-days", type=int)
|
|
148
|
+
parser.add_argument("--require-release-eligible", action="store_true")
|
|
149
|
+
parser.add_argument("--verify-snapshot", action="store_true",
|
|
150
|
+
help="check current package bytes against the Gate 5 commit even when release is blocked")
|
|
151
|
+
parser.add_argument("--json", action="store_true")
|
|
152
|
+
args = parser.parse_args(argv)
|
|
153
|
+
findings = check_skills(args.skills_root, max_age_days=args.max_age_days)
|
|
154
|
+
# The release ledger (gates.json) is optional: the governance metadata lint
|
|
155
|
+
# above stands on its own. Only check the release state when a ledger exists,
|
|
156
|
+
# or when the caller explicitly asked to (so an intended check still fails
|
|
157
|
+
# loudly on a missing ledger rather than passing silently).
|
|
158
|
+
if args.status_file.exists() or args.require_release_eligible or args.verify_snapshot:
|
|
159
|
+
findings += check_status(args.status_file,
|
|
160
|
+
require_release_eligible=args.require_release_eligible,
|
|
161
|
+
verify_snapshot=args.verify_snapshot, skills_root=args.skills_root)
|
|
162
|
+
report = {"finding_count": len(findings), "findings": findings,
|
|
163
|
+
"release_check": args.require_release_eligible}
|
|
164
|
+
if args.json:
|
|
165
|
+
print(json.dumps(report, indent=2, sort_keys=True))
|
|
166
|
+
else:
|
|
167
|
+
for finding in findings:
|
|
168
|
+
print(f"ERROR: {finding['skill']}: {finding['code']}: {finding['message']}")
|
|
169
|
+
print(f"{len(findings)} governance finding(s)")
|
|
170
|
+
return 1 if findings else 0
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if __name__ == "__main__":
|
|
174
|
+
raise SystemExit(main())
|