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,97 @@
|
|
|
1
|
+
"""Guard: the credential SCOPE (profile + workspace) reaches every inner
|
|
2
|
+
`procesio` call.
|
|
3
|
+
|
|
4
|
+
Regression. `verify` and `audit` used to forward only `--profile`, so any
|
|
5
|
+
process outside the profile's default workspace failed with HTTP 400
|
|
6
|
+
`{"statusCode": 501, "value": "User is not authorized for the requested
|
|
7
|
+
resource."}` - and a user/password profile cannot carry a workspace of its own,
|
|
8
|
+
so there was no workaround at all. The scope must be splatted into EVERY inner
|
|
9
|
+
invoke, not just the first one: the gate fetches, validates, runs, and reads
|
|
10
|
+
instance status, and each of those is a separately scoped call.
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
|
|
16
|
+
from agents.procesio import verifylib
|
|
17
|
+
from agents.procesio.handlers import audit as audit_h
|
|
18
|
+
from agents.procesio.handlers import verify as verify_h
|
|
19
|
+
from agents.procesio.tests.conftest import action, flow
|
|
20
|
+
|
|
21
|
+
WS = "3fd85e9d-121e-415b-877f-f488cd685ce3"
|
|
22
|
+
START = action("Start")
|
|
23
|
+
CONFIGURED = action("Add", params=[{"Value": "x", "Variable": []}],
|
|
24
|
+
settings=[{"value": "x"}])
|
|
25
|
+
STOP = action("Stop")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class _Ctx:
|
|
29
|
+
def __init__(self, invoke):
|
|
30
|
+
self.invoke = invoke
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse(add_args, argv):
|
|
34
|
+
p = argparse.ArgumentParser()
|
|
35
|
+
add_args(p)
|
|
36
|
+
return p.parse_args(argv)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _flags(call_args: list, flag: str):
|
|
40
|
+
"""The value passed for `flag` in one recorded invoke, or None."""
|
|
41
|
+
return call_args[call_args.index(flag) + 1] if flag in call_args else None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_scope_args_builds_both_flags():
|
|
45
|
+
assert verifylib.scope_args("account", WS) == [
|
|
46
|
+
"--profile", "account", "--workspace-id", WS]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_scope_args_omits_what_was_not_given():
|
|
50
|
+
assert verifylib.scope_args(None, None) == []
|
|
51
|
+
assert verifylib.scope_args("account", None) == ["--profile", "account"]
|
|
52
|
+
assert verifylib.scope_args(None, WS) == ["--workspace-id", WS]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_verify_forwards_workspace_to_every_inner_call(fake_invoke):
|
|
56
|
+
fake_invoke.set("get-process", flow([START, CONFIGURED, STOP]))
|
|
57
|
+
fake_invoke.set("request", {"result": {"isValid": True}})
|
|
58
|
+
fake_invoke.set("run-process", {"result": {"id": "iid", "status": 50}})
|
|
59
|
+
fake_invoke.set("get-instance-status", {"result": {"status": 50, "actions": []}})
|
|
60
|
+
|
|
61
|
+
verifylib.verify_process(fake_invoke, "pid", profile="account",
|
|
62
|
+
workspace_id=WS, run=True)
|
|
63
|
+
|
|
64
|
+
seen = {a for _, a, _ in fake_invoke.calls}
|
|
65
|
+
assert seen == {"get-process", "request", "run-process", "get-instance-status"}
|
|
66
|
+
for _tool, action_name, args in fake_invoke.calls:
|
|
67
|
+
assert _flags(args, "--workspace-id") == WS, f"{action_name} lost the workspace"
|
|
68
|
+
assert _flags(args, "--profile") == "account", f"{action_name} lost the profile"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_verify_without_workspace_sends_no_flag(fake_invoke):
|
|
72
|
+
"""Omitting it must stay a no-op, so the profile's own workspace still works."""
|
|
73
|
+
fake_invoke.set("get-process", flow([START, CONFIGURED, STOP]))
|
|
74
|
+
fake_invoke.set("request", {"result": {"isValid": True}})
|
|
75
|
+
verifylib.verify_process(fake_invoke, "pid", profile="account")
|
|
76
|
+
assert all("--workspace-id" not in args for _t, _a, args in fake_invoke.calls)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_verify_handler_threads_the_flag(fake_invoke):
|
|
80
|
+
fake_invoke.set("get-process", flow([START, CONFIGURED, STOP]))
|
|
81
|
+
fake_invoke.set("request", {"result": {"isValid": True}})
|
|
82
|
+
args = _parse(verify_h._args,
|
|
83
|
+
["--process-id", "pid", "--profile", "account", "--workspace-id", WS])
|
|
84
|
+
verify_h._verify(_Ctx(fake_invoke), args)
|
|
85
|
+
assert _flags(fake_invoke.calls[0][2], "--workspace-id") == WS
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_audit_handler_threads_the_flag(fake_invoke):
|
|
89
|
+
fake_invoke.set("get-process", flow([START, CONFIGURED, STOP]))
|
|
90
|
+
args = _parse(audit_h._args,
|
|
91
|
+
["--process-id", "pid", "--profile", "account", "--workspace-id", WS])
|
|
92
|
+
report = audit_h._audit(_Ctx(fake_invoke), args)
|
|
93
|
+
assert report["process_id"] == "pid"
|
|
94
|
+
tool, action_name, call_args = fake_invoke.calls[0]
|
|
95
|
+
assert (tool, action_name) == ("procesio", "get-process")
|
|
96
|
+
assert _flags(call_args, "--workspace-id") == WS
|
|
97
|
+
assert _flags(call_args, "--profile") == "account"
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""The `verify` gate: run the automatable self-test steps against a live process.
|
|
2
|
+
|
|
3
|
+
Turns the playbook checklist from prose into an executable gate. It drives the
|
|
4
|
+
`procesio` tool (never the API directly) and is defensive: a tool error or an
|
|
5
|
+
unexpected response shape downgrades a check to `skip` with the reason, so the
|
|
6
|
+
gate reports the truth instead of crashing or lying. Manual steps it cannot run
|
|
7
|
+
are returned in `manual_checks` so they cannot be silently skipped.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import tempfile
|
|
14
|
+
from typing import Any, Callable
|
|
15
|
+
|
|
16
|
+
from agents._lib.toolrunner import ToolError
|
|
17
|
+
from agents.procesio import audit, checklist
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def scope_args(profile: str | None, workspace_id: str | None = None) -> list[str]:
|
|
21
|
+
"""The credential-scope flags that EVERY inner `procesio` call must forward.
|
|
22
|
+
|
|
23
|
+
Forwarding `--profile` alone is not enough: a session is bound to one default
|
|
24
|
+
workspace, so a resource living in any other workspace answers HTTP 400
|
|
25
|
+
`{"statusCode": 501, "value": "User is not authorized for the requested
|
|
26
|
+
resource."}` unless the `workspaceid` header is set per call, which is what
|
|
27
|
+
`--workspace-id` does. Only an api-key profile can carry a workspace of its
|
|
28
|
+
own, so for a user/password profile there is no fallback - the flag is the
|
|
29
|
+
only way to reach another workspace. Build the flags here and splat them into
|
|
30
|
+
every invoke, so a new inner call cannot forget one.
|
|
31
|
+
"""
|
|
32
|
+
args: list[str] = []
|
|
33
|
+
if profile:
|
|
34
|
+
args += ["--profile", profile]
|
|
35
|
+
if workspace_id:
|
|
36
|
+
args += ["--workspace-id", workspace_id]
|
|
37
|
+
return args
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _flow_from(data: dict) -> dict:
|
|
41
|
+
"""Unwrap get-process. Live API and tests both nest the flow under result.flow
|
|
42
|
+
(camelCase live, but ci() is case-insensitive)."""
|
|
43
|
+
res = data.get("result") if isinstance(data, dict) else None
|
|
44
|
+
if isinstance(res, dict):
|
|
45
|
+
f = audit.ci(res, "flow")
|
|
46
|
+
return f if isinstance(f, dict) else res
|
|
47
|
+
return data if isinstance(data, dict) else {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _check(cid: str, phase: str, status: str, detail: Any) -> dict:
|
|
51
|
+
return {"id": cid, "phase": phase, "status": status, "detail": detail}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _instance_ids(res: dict) -> tuple[str | None, Any]:
|
|
55
|
+
if not isinstance(res, dict):
|
|
56
|
+
return None, None
|
|
57
|
+
inst = audit.ci(res, "instance")
|
|
58
|
+
inst = inst if isinstance(inst, dict) else res
|
|
59
|
+
iid = audit.ci(inst, "id", "instanceId", "flowInstanceId") or \
|
|
60
|
+
audit.ci(res, "instanceId", "id")
|
|
61
|
+
status = audit.ci(inst, "status")
|
|
62
|
+
if status is None:
|
|
63
|
+
status = audit.ci(res, "status")
|
|
64
|
+
return (str(iid) if iid else None), status
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _validation_messages(details: dict):
|
|
68
|
+
"""PROCESIO's /api/Projects/validate returns HTTP 400 with a list of
|
|
69
|
+
{statusCode, value, target} when a process is invalid (the tool surfaces that
|
|
70
|
+
as an error envelope). Return that list (possibly empty = valid) for a real
|
|
71
|
+
validation response, or None when this is not one (e.g. a 500 / wrong shape)."""
|
|
72
|
+
if not isinstance(details, dict) or details.get("status") != 400:
|
|
73
|
+
return None
|
|
74
|
+
body = details.get("body")
|
|
75
|
+
inner = body.get("body") if isinstance(body, dict) else body
|
|
76
|
+
return inner if isinstance(inner, list) else None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _action_errors(status_res: dict) -> list[dict]:
|
|
80
|
+
inst = audit.ci(status_res, "instance")
|
|
81
|
+
inst = inst if isinstance(inst, dict) else status_res
|
|
82
|
+
actions = audit.ci(inst, "actions")
|
|
83
|
+
out = []
|
|
84
|
+
for a in actions or []:
|
|
85
|
+
if isinstance(a, dict) and audit.ci(a, "errorMessage"):
|
|
86
|
+
out.append({"action": audit.ci(a, "actionName", "name"),
|
|
87
|
+
"errorMessage": audit.ci(a, "errorMessage")})
|
|
88
|
+
return out
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def verify_process(invoke: Callable, process_id: str, *, profile: str | None = None,
|
|
92
|
+
workspace_id: str | None = None,
|
|
93
|
+
run: bool = False, payload: str | None = None,
|
|
94
|
+
timeout: int | None = None) -> dict:
|
|
95
|
+
checks: list[dict] = []
|
|
96
|
+
scope = scope_args(profile, workspace_id)
|
|
97
|
+
|
|
98
|
+
# 1. fetch -----------------------------------------------------------------
|
|
99
|
+
try:
|
|
100
|
+
flow = _flow_from(invoke("procesio", "get-process", "--id", process_id, *scope))
|
|
101
|
+
except ToolError as e:
|
|
102
|
+
return {"process_id": process_id, "verdict": "fail",
|
|
103
|
+
"checks": [_check("fetch", "validate", "fail",
|
|
104
|
+
{"code": e.code, "message": e.message})],
|
|
105
|
+
"manual_checks": checklist.manual_steps()}
|
|
106
|
+
title = audit.ci(flow, "title", "name")
|
|
107
|
+
checks.append(_check("fetch", "validate", "pass", {"title": title}))
|
|
108
|
+
|
|
109
|
+
# 2. validate --------------------------------------------------------------
|
|
110
|
+
# The flow JSON is often large; send it via a temp file (--body-file), never as an
|
|
111
|
+
# inline --body argv. A big process overflows the OS command-line limit (Windows
|
|
112
|
+
# WinError 206 "filename or extension is too long" / POSIX E2BIG), which crashed the
|
|
113
|
+
# gate on exactly the real processes it must check.
|
|
114
|
+
bf = tempfile.NamedTemporaryFile("w", suffix=".json", delete=False, encoding="utf-8")
|
|
115
|
+
try:
|
|
116
|
+
json.dump(flow, bf, ensure_ascii=False)
|
|
117
|
+
bf.close()
|
|
118
|
+
vd = invoke("procesio", "request", "--method", "POST",
|
|
119
|
+
"--path", "/api/Projects/validate",
|
|
120
|
+
"--body-file", bf.name, *scope)
|
|
121
|
+
res = vd.get("result")
|
|
122
|
+
errors = None
|
|
123
|
+
if isinstance(res, dict):
|
|
124
|
+
errors = audit.ci(res, "validationErrors", "errors", "messages")
|
|
125
|
+
valid = audit.ci(res, "isValid", "valid")
|
|
126
|
+
else:
|
|
127
|
+
valid = None
|
|
128
|
+
if errors:
|
|
129
|
+
checks.append(_check("validate-process", "validate", "warn",
|
|
130
|
+
{"errors": errors}))
|
|
131
|
+
elif valid is False:
|
|
132
|
+
checks.append(_check("validate-process", "validate", "warn",
|
|
133
|
+
{"valid": False, "raw": res}))
|
|
134
|
+
else:
|
|
135
|
+
checks.append(_check("validate-process", "validate", "pass",
|
|
136
|
+
{"valid": True if valid else "no errors reported"}))
|
|
137
|
+
except ToolError as e:
|
|
138
|
+
msgs = _validation_messages(e.details)
|
|
139
|
+
if msgs is not None:
|
|
140
|
+
checks.append(_check("validate-process", "validate",
|
|
141
|
+
"warn" if msgs else "pass",
|
|
142
|
+
{"errors": msgs} if msgs else {"valid": True}))
|
|
143
|
+
else:
|
|
144
|
+
checks.append(_check("validate-process", "validate", "skip",
|
|
145
|
+
{"reason": "validate endpoint not callable",
|
|
146
|
+
"code": e.code, "message": e.message,
|
|
147
|
+
"detail": e.details}))
|
|
148
|
+
finally:
|
|
149
|
+
try:
|
|
150
|
+
os.unlink(bf.name)
|
|
151
|
+
except OSError:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
# 3. config parity (gating correctness audit) ------------------------------
|
|
155
|
+
cf = audit.correctness_findings(flow)
|
|
156
|
+
blocking = [f for f in cf if f["severity"] in ("warn", "fail")]
|
|
157
|
+
if blocking:
|
|
158
|
+
# a correctness finding marked `fail` (e.g. a Call-API node masquerading as a
|
|
159
|
+
# Data Store/cache op) is a hard defect, not a smell - fail the gate outright.
|
|
160
|
+
hard = any(f["severity"] == "fail" for f in blocking)
|
|
161
|
+
checks.append(_check("config-parity-audit", "validate",
|
|
162
|
+
"fail" if hard else "warn",
|
|
163
|
+
{"findings": blocking}))
|
|
164
|
+
else:
|
|
165
|
+
checks.append(_check("config-parity-audit", "validate", "pass",
|
|
166
|
+
{"findings": cf}))
|
|
167
|
+
|
|
168
|
+
# 4. run + instance status -------------------------------------------------
|
|
169
|
+
if run:
|
|
170
|
+
try:
|
|
171
|
+
args = ["run-process", "--id", process_id, "--synchronous"]
|
|
172
|
+
if payload:
|
|
173
|
+
args += ["--payload", payload]
|
|
174
|
+
if timeout:
|
|
175
|
+
args += ["--timeout", str(timeout)]
|
|
176
|
+
rd = invoke("procesio", *args, *scope)
|
|
177
|
+
iid, status_code = _instance_ids(rd.get("result") or {})
|
|
178
|
+
action_errors: list[dict] = []
|
|
179
|
+
if iid:
|
|
180
|
+
try:
|
|
181
|
+
sd = invoke("procesio", "get-instance-status", "--id", iid,
|
|
182
|
+
"--flow-template-id", process_id, "--actions", *scope)
|
|
183
|
+
sres = sd.get("result") or {}
|
|
184
|
+
s2 = _instance_ids(sres)[1]
|
|
185
|
+
status_code = s2 if s2 is not None else status_code
|
|
186
|
+
action_errors = _action_errors(sres)
|
|
187
|
+
except ToolError:
|
|
188
|
+
pass
|
|
189
|
+
if status_code == 50 and not action_errors:
|
|
190
|
+
checks.append(_check("run-instance", "run", "pass",
|
|
191
|
+
{"instance_id": iid, "status": 50}))
|
|
192
|
+
elif status_code == 40 or action_errors:
|
|
193
|
+
checks.append(_check("run-instance", "run", "fail",
|
|
194
|
+
{"instance_id": iid, "status": status_code,
|
|
195
|
+
"action_errors": action_errors}))
|
|
196
|
+
else:
|
|
197
|
+
checks.append(_check("run-instance", "run", "warn",
|
|
198
|
+
{"instance_id": iid, "status": status_code,
|
|
199
|
+
"note": "unrecognized status; inspect manually"}))
|
|
200
|
+
except ToolError as e:
|
|
201
|
+
checks.append(_check("run-instance", "run", "fail",
|
|
202
|
+
{"code": e.code, "message": e.message}))
|
|
203
|
+
else:
|
|
204
|
+
checks.append(_check("run-instance", "run", "skip",
|
|
205
|
+
{"reason": "not run; pass --run to execute the process"}))
|
|
206
|
+
|
|
207
|
+
# practice findings (non-gating) + verdict ---------------------------------
|
|
208
|
+
full = audit.audit_process(flow)
|
|
209
|
+
practice = [f for f in full["findings"] if f["kind"] == "practice"]
|
|
210
|
+
statuses = [c["status"] for c in checks]
|
|
211
|
+
verdict = "fail" if "fail" in statuses else ("warn" if "warn" in statuses else "pass")
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
"process_id": process_id,
|
|
215
|
+
"title": title,
|
|
216
|
+
"verdict": verdict,
|
|
217
|
+
"ran": run,
|
|
218
|
+
"checks": checks,
|
|
219
|
+
"practice_findings": practice,
|
|
220
|
+
"manual_checks": checklist.manual_steps(),
|
|
221
|
+
"summary": full["summary"],
|
|
222
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Setup & Health Dashboard
|
|
2
|
+
|
|
3
|
+
A local web console for setting up and monitoring the framework. Built for
|
|
4
|
+
onboarding: a colleague who has just cloned the repo can see every tool, agent,
|
|
5
|
+
and skill, see exactly what each one is missing, and perform every setup action
|
|
6
|
+
from the browser instead of the terminal or a chat with Claude.
|
|
7
|
+
|
|
8
|
+
It is a framework component (like `scripts/`), not a registered tool - it is a
|
|
9
|
+
long-running local server, not a JSON-in/JSON-out command. It carries **zero
|
|
10
|
+
user data**: all state stays under `context-state-knowledge/` via
|
|
11
|
+
`tools/_lib/userdata.py`, so the wipe-safe boundary is intact.
|
|
12
|
+
|
|
13
|
+
## Launch
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
python dashboard/serve.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
It binds to `127.0.0.1` only, prints a URL containing a one-time token, and opens
|
|
20
|
+
your browser. Options: `--port <n>`, `--no-browser`, `--host` (loopback only).
|
|
21
|
+
|
|
22
|
+
> Run it from a terminal (it needs an interactive console for the credential
|
|
23
|
+
> store). If you launch it from a detached/service context, force the backend
|
|
24
|
+
> with `PYTHON_KEYRING_BACKEND=keyring.backends.Windows.WinVaultKeyring`
|
|
25
|
+
> (serve.py already sets this).
|
|
26
|
+
|
|
27
|
+
## What you get
|
|
28
|
+
|
|
29
|
+
- **Inventory** - every tool, agent, and skill from the live registry, grouped
|
|
30
|
+
into tabs, each with a readiness dot, its description, and its actions.
|
|
31
|
+
- **Credential status** - per secret: present or missing, with a one-click
|
|
32
|
+
**Store** / **update** / **delete**. Values go straight to Windows Credential
|
|
33
|
+
Manager and are never written to disk or logged.
|
|
34
|
+
- **Live validation** - beyond "present", each capability with a probe is
|
|
35
|
+
actively checked: **connected**, **invalid** (with the error), or **no live
|
|
36
|
+
probe**. Streams in as results land; **Re-check all** re-runs it.
|
|
37
|
+
- **Config editor** - the LLM Providers tab and each config template open a
|
|
38
|
+
validated JSON editor. `llm/providers.json` is schema-checked; every config
|
|
39
|
+
is scanned for leftover template placeholders.
|
|
40
|
+
- **Web login** - tools that log in via a browser declare a `web_session:` block
|
|
41
|
+
(ryver-web, whatsapp, quickmail-web, fgo-web, linkedin-web, the *-invoices tools).
|
|
42
|
+
Their card shows a **Connect** button prefilled with the right session name and
|
|
43
|
+
URL - no guessing - and a missing login counts as needs-setup.
|
|
44
|
+
- **OAuth** - tools with an `auth-login` action (google-*, linkedin) show a
|
|
45
|
+
**Connect** button on the card; the oauth token/accounts secrets (produced by
|
|
46
|
+
the flow, not typed) are hidden so only the client key is settable.
|
|
47
|
+
- **Bootstrap** - on a fresh install a banner offers one-click
|
|
48
|
+
`orchestrator bootstrap --with-templates`.
|
|
49
|
+
- **Plain-language status** - each card leads with one line - "Ready to use",
|
|
50
|
+
"Needs a credential", "Needs a browser login", "Needs Google/LinkedIn sign-in",
|
|
51
|
+
or "Not working" - and only shows a live-check row where a probe exists. When a
|
|
52
|
+
check fails, an **Explain** button asks the LLM why.
|
|
53
|
+
- **LLM-backed verification & copilot** - once an LLM provider is configured, the
|
|
54
|
+
Context tab summarizes what the store knows, **Explain** judges a failing probe,
|
|
55
|
+
and **Copilot** answers setup questions with one-click suggested actions. All of
|
|
56
|
+
this goes through the provider-agnostic `llm` tool - the dashboard never calls
|
|
57
|
+
Claude or any hardcoded provider.
|
|
58
|
+
|
|
59
|
+
## The live-validation convention
|
|
60
|
+
|
|
61
|
+
"Is the credential actually connected?" is answered by a probe resolved in this
|
|
62
|
+
order per capability:
|
|
63
|
+
|
|
64
|
+
1. an explicit `healthcheck:` block in the manifest (a cheap, read-only action),
|
|
65
|
+
2. else a conventional `auth-status` action,
|
|
66
|
+
3. else **no live probe** (presence only).
|
|
67
|
+
|
|
68
|
+
A capability with a missing secret is not probed - it is already known
|
|
69
|
+
unconfigured. To make a tool live-validatable, add to its `tool.yaml`:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
healthcheck:
|
|
73
|
+
action: list-users # a cheap, read-only, side-effect-free action
|
|
74
|
+
args: { limit: 1 } # forwarded as --limit 1
|
|
75
|
+
label: "list one user"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Probes run concurrently, cache briefly, and are single-flighted so a client can
|
|
79
|
+
never storm the machine.
|
|
80
|
+
|
|
81
|
+
## Security model
|
|
82
|
+
|
|
83
|
+
Single user, own laptop. The server binds loopback only and gates every `/api/*`
|
|
84
|
+
call with a one-time token (in the launch URL, then stripped from the address
|
|
85
|
+
bar). It is **not** multi-user auth - that is out of scope until a shared/remote
|
|
86
|
+
mode is built. No GET ever returns a stored secret value.
|
|
87
|
+
|
|
88
|
+
## Architecture
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
dashboard/
|
|
92
|
+
serve.py launcher (venv re-exec, loopback bind, token)
|
|
93
|
+
server/
|
|
94
|
+
handler.py routing, token gate, JSON + SSE + static
|
|
95
|
+
routes.py URL -> handler wiring
|
|
96
|
+
inventory.py read model (in-process: registry + store + providers)
|
|
97
|
+
validate.py live probes (concurrent, cached, single-flight)
|
|
98
|
+
setup.py credentials, config, bootstrap, sessions, OAuth
|
|
99
|
+
jobs.py background jobs for interactive logins
|
|
100
|
+
config_schemas.py per-config validation (jsonschema + placeholder scan)
|
|
101
|
+
llmtest.py provider-agnostic tests, context inspect, copilot
|
|
102
|
+
runner.py subprocess bridge to the framework scripts
|
|
103
|
+
security.py loopback token
|
|
104
|
+
web/ vanilla JS + CSS SPA (no build step, no npm)
|
|
105
|
+
tests/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Reads are in-process (fast, always current). Anything that runs a tool/agent or
|
|
109
|
+
writes a credential goes through the existing scripts as a subprocess, so each
|
|
110
|
+
runs exactly as it does from the terminal - the dashboard never reimplements a
|
|
111
|
+
tool's logic or credential handling.
|
|
112
|
+
|
|
113
|
+
## Tests
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
.venv\Scripts\python.exe -m pytest dashboard/tests -q
|
|
117
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Framework setup & health dashboard.
|
|
2
|
+
|
|
3
|
+
A local, single-user web console for onboarding: see every tool, agent, skill,
|
|
4
|
+
and the context/state store; see exactly what each is missing; and perform every
|
|
5
|
+
setup action (store credentials, fill config, capture logins, verify) from the UI
|
|
6
|
+
instead of the terminal or a chat with Claude.
|
|
7
|
+
|
|
8
|
+
Not a JSON-in/JSON-out tool (it is a long-running local server), so it lives here
|
|
9
|
+
as its own framework component beside scripts/, tools/, agents/, skills/. It
|
|
10
|
+
carries ZERO user data: all state stays under context-state-knowledge/ resolved
|
|
11
|
+
through tools/_lib/userdata.py, keeping the wipe-safe boundary intact.
|
|
12
|
+
|
|
13
|
+
LLM-agnostic: any model work (functional tests, context inspection, the setup
|
|
14
|
+
copilot) goes through the `llm` tool, which is provider-neutral. The dashboard
|
|
15
|
+
never calls Claude or any hardcoded provider.
|
|
16
|
+
|
|
17
|
+
Launch: python dashboard/serve.py
|
|
18
|
+
"""
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Launch the framework setup & health dashboard.
|
|
2
|
+
|
|
3
|
+
python dashboard/serve.py [--port 8765] [--host 127.0.0.1] [--no-browser]
|
|
4
|
+
|
|
5
|
+
Binds to loopback only, mints a one-time access token, prints the URL, and opens
|
|
6
|
+
the browser. Stdlib http.server (ThreadingHTTPServer) - no web framework, no
|
|
7
|
+
install step, so a colleague who has only cloned the repo can run it immediately.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
# Force keyring's Windows backend explicitly. keyring's default backend
|
|
16
|
+
# AUTO-DETECTION probes several backends and blocks when the process has no
|
|
17
|
+
# interactive console (as a server launched from a preview manager, a service,
|
|
18
|
+
# or a detached shell does) - which would hang the very first credential read.
|
|
19
|
+
# Naming the backend skips detection entirely and still uses the real Windows
|
|
20
|
+
# Credential Manager. Subprocesses (run-tool / set-credential) inherit this env.
|
|
21
|
+
os.environ.setdefault("PYTHON_KEYRING_BACKEND", "keyring.backends.Windows.WinVaultKeyring")
|
|
22
|
+
|
|
23
|
+
# Auto-switch to the project's .venv Python (keyring/pydantic/yaml live there).
|
|
24
|
+
_PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
25
|
+
_VENV_PY = _PROJECT_ROOT / ".venv" / "Scripts" / "python.exe"
|
|
26
|
+
if _VENV_PY.exists() and Path(sys.executable).resolve() != _VENV_PY.resolve():
|
|
27
|
+
import subprocess
|
|
28
|
+
sys.exit(subprocess.run([str(_VENV_PY), __file__, *sys.argv[1:]]).returncode)
|
|
29
|
+
|
|
30
|
+
sys.path.insert(0, str(_PROJECT_ROOT))
|
|
31
|
+
|
|
32
|
+
import argparse # noqa: E402
|
|
33
|
+
import socket # noqa: E402
|
|
34
|
+
import threading # noqa: E402
|
|
35
|
+
import webbrowser # noqa: E402
|
|
36
|
+
from http.server import ThreadingHTTPServer # noqa: E402
|
|
37
|
+
|
|
38
|
+
from dashboard.server import security # noqa: E402
|
|
39
|
+
from dashboard.server.handler import Handler # noqa: E402
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _free_port(host: str, preferred: int) -> int:
|
|
43
|
+
"""Use the preferred port if free, else let the OS pick one."""
|
|
44
|
+
for candidate in (preferred, 0):
|
|
45
|
+
try:
|
|
46
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
47
|
+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
48
|
+
s.bind((host, candidate))
|
|
49
|
+
port = s.getsockname()[1]
|
|
50
|
+
s.close()
|
|
51
|
+
return port
|
|
52
|
+
except OSError:
|
|
53
|
+
continue
|
|
54
|
+
raise SystemExit("could not bind a local port")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def main() -> int:
|
|
58
|
+
p = argparse.ArgumentParser(description="Framework setup & health dashboard.")
|
|
59
|
+
p.add_argument("--host", default="127.0.0.1",
|
|
60
|
+
help="Bind address (loopback only; do not expose).")
|
|
61
|
+
p.add_argument("--port", type=int, default=8765)
|
|
62
|
+
p.add_argument("--no-browser", action="store_true",
|
|
63
|
+
help="Do not auto-open the browser.")
|
|
64
|
+
args = p.parse_args()
|
|
65
|
+
|
|
66
|
+
if args.host not in ("127.0.0.1", "localhost", "::1"):
|
|
67
|
+
print(f"refusing to bind non-loopback host {args.host!r}: this dashboard "
|
|
68
|
+
"stores credentials and is single-user, local-only.", file=sys.stderr)
|
|
69
|
+
return 2
|
|
70
|
+
|
|
71
|
+
port = _free_port(args.host, args.port)
|
|
72
|
+
url = f"http://{args.host}:{port}/?token={security.token()}"
|
|
73
|
+
|
|
74
|
+
httpd = ThreadingHTTPServer((args.host, port), Handler)
|
|
75
|
+
httpd.daemon_threads = True
|
|
76
|
+
|
|
77
|
+
print("=" * 68)
|
|
78
|
+
print(" Agents & Tools - Setup & Health Dashboard")
|
|
79
|
+
print("=" * 68)
|
|
80
|
+
print(f" Open: {url}")
|
|
81
|
+
print(" Bound to loopback only. The token gates the API; keep the URL private.")
|
|
82
|
+
print(" Press Ctrl+C to stop.")
|
|
83
|
+
print("=" * 68)
|
|
84
|
+
|
|
85
|
+
if not args.no_browser:
|
|
86
|
+
threading.Timer(0.5, lambda: webbrowser.open(url)).start()
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
httpd.serve_forever()
|
|
90
|
+
except KeyboardInterrupt:
|
|
91
|
+
print("\nshutting down.")
|
|
92
|
+
finally:
|
|
93
|
+
httpd.server_close()
|
|
94
|
+
return 0
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
if __name__ == "__main__":
|
|
98
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Dashboard HTTP server package (Python stdlib only - no web framework)."""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Per-config validation for the config editor.
|
|
2
|
+
|
|
3
|
+
Two layers:
|
|
4
|
+
1. A precise JSON Schema for configs where structure matters - notably
|
|
5
|
+
llm/providers.json, which gates every LLM-backed feature. jsonschema
|
|
6
|
+
(already a framework dependency) does the heavy lifting.
|
|
7
|
+
2. A generic pass for every config: it must be a JSON object, and any value
|
|
8
|
+
still holding a template PLACEHOLDER (YOUR-..., REPLACE_ME, <...>) is
|
|
9
|
+
flagged so a half-filled config never reads as ready.
|
|
10
|
+
|
|
11
|
+
Returns {ok, errors, warnings}. `ok` is False only on a hard schema/JSON error;
|
|
12
|
+
leftover placeholders are warnings (the user may be mid-edit).
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
import jsonschema
|
|
21
|
+
except Exception: # noqa: BLE001 - degrade to generic checks if absent
|
|
22
|
+
jsonschema = None
|
|
23
|
+
|
|
24
|
+
_PLACEHOLDER = re.compile(r"YOUR[-_ ]|REPLACE|CHANGE[-_ ]?ME|<[^>]+>|xxxxx", re.I)
|
|
25
|
+
|
|
26
|
+
# component/name (without .json) -> JSON Schema
|
|
27
|
+
_SCHEMAS: dict[str, dict] = {
|
|
28
|
+
"llm/providers": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["providers"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"comment": {"type": "string"},
|
|
33
|
+
"default": {"type": "string"},
|
|
34
|
+
"providers": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"minProperties": 1,
|
|
37
|
+
"additionalProperties": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"required": ["adapter"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"adapter": {"enum": ["openai_compat", "claude_api", "codex_cli"]},
|
|
42
|
+
"base_url": {"type": "string"},
|
|
43
|
+
"model": {"type": "string"},
|
|
44
|
+
"auth_style": {"enum": ["bearer", "api-key", "none"]},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _walk_placeholders(node: Any, path: str, out: list[str]) -> None:
|
|
54
|
+
if isinstance(node, str):
|
|
55
|
+
if _PLACEHOLDER.search(node):
|
|
56
|
+
out.append(f"{path or '(root)'}: still a placeholder ({node!r})")
|
|
57
|
+
elif isinstance(node, dict):
|
|
58
|
+
for k, v in node.items():
|
|
59
|
+
_walk_placeholders(v, f"{path}.{k}" if path else k, out)
|
|
60
|
+
elif isinstance(node, list):
|
|
61
|
+
for i, v in enumerate(node):
|
|
62
|
+
_walk_placeholders(v, f"{path}[{i}]", out)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def validate(component: str, name: str, data: Any) -> dict[str, Any]:
|
|
66
|
+
errors: list[str] = []
|
|
67
|
+
warnings: list[str] = []
|
|
68
|
+
|
|
69
|
+
if not isinstance(data, dict):
|
|
70
|
+
return {"ok": False, "errors": ["top-level value must be a JSON object"],
|
|
71
|
+
"warnings": []}
|
|
72
|
+
|
|
73
|
+
schema = _SCHEMAS.get(f"{component}/{name}")
|
|
74
|
+
if schema is not None and jsonschema is not None:
|
|
75
|
+
validator = jsonschema.Draft7Validator(schema)
|
|
76
|
+
for err in sorted(validator.iter_errors(data), key=lambda e: list(e.path)):
|
|
77
|
+
loc = ".".join(str(p) for p in err.path) or "(root)"
|
|
78
|
+
errors.append(f"{loc}: {err.message}")
|
|
79
|
+
# cross-field: `default` must name an existing provider
|
|
80
|
+
if component == "llm" and name == "providers":
|
|
81
|
+
default = data.get("default")
|
|
82
|
+
provs = data.get("providers") or {}
|
|
83
|
+
if default and default not in provs:
|
|
84
|
+
errors.append(f"default: {default!r} is not one of the providers "
|
|
85
|
+
f"({', '.join(provs) or 'none'})")
|
|
86
|
+
|
|
87
|
+
_walk_placeholders(data, "", warnings)
|
|
88
|
+
return {"ok": not errors, "errors": errors, "warnings": warnings}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def has_schema(component: str, name: str) -> bool:
|
|
92
|
+
return f"{component}/{name}" in _SCHEMAS
|