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.
Files changed (647) hide show
  1. procesio_cli/__init__.py +18 -0
  2. procesio_cli/_cli.py +71 -0
  3. procesio_cli/agents/__init__.py +0 -0
  4. procesio_cli/agents/_lib/__init__.py +0 -0
  5. procesio_cli/agents/_lib/actiondef.py +24 -0
  6. procesio_cli/agents/_lib/errors.py +40 -0
  7. procesio_cli/agents/_lib/reversibility.py +236 -0
  8. procesio_cli/agents/_lib/toolrunner.py +141 -0
  9. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PLAYBOOK.md +62 -0
  10. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PROCESIO-INTEROP.md +76 -0
  11. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-TROUBLESHOOTING.md +60 -0
  12. procesio_cli/agents/connector-builder/README.md +51 -0
  13. procesio_cli/agents/connector-builder/agent.yaml +61 -0
  14. procesio_cli/agents/connector-builder/context.py +19 -0
  15. procesio_cli/agents/connector-builder/handlers/__init__.py +1 -0
  16. procesio_cli/agents/connector-builder/handlers/checklist.py +71 -0
  17. procesio_cli/agents/connector-builder/handlers/guidance.py +37 -0
  18. procesio_cli/agents/connector-builder/handlers/nextstep.py +221 -0
  19. procesio_cli/agents/connector-builder/handlers/status.py +35 -0
  20. procesio_cli/agents/connector-builder/knowledge.py +47 -0
  21. procesio_cli/agents/connector-builder/main.py +93 -0
  22. procesio_cli/agents/connector-builder/tests/conftest.py +95 -0
  23. procesio_cli/agents/connector-builder/tests/test_cba_agent.py +148 -0
  24. procesio_cli/agents/orchestrator/__init__.py +0 -0
  25. procesio_cli/agents/orchestrator/bootstraplib.py +166 -0
  26. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/00-INDEX.md +60 -0
  27. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/01-PROCESSES.md +230 -0
  28. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/02-FORMS.md +287 -0
  29. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/03-INTEGRATIONS.md +384 -0
  30. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/04-DATABASE.md +293 -0
  31. procesio_cli/agents/procesio/PROCESIO-API-RELIABILITY-DOCTRINE.md +113 -0
  32. procesio_cli/agents/procesio/PROCESIO-BEST-PRACTICES.md +316 -0
  33. procesio_cli/agents/procesio/PROCESIO-BUILD-AND-TEST-PLAYBOOK.md +217 -0
  34. procesio_cli/agents/procesio/PROCESIO-DATASTORE.md +72 -0
  35. procesio_cli/agents/procesio/PROCESIO-ENVIRONMENTS.md +62 -0
  36. procesio_cli/agents/procesio/PROCESIO-SCHEDULING.md +47 -0
  37. procesio_cli/agents/procesio/PROCESIO-VISUAL-ORGANIZATION.md +175 -0
  38. procesio_cli/agents/procesio/README.md +97 -0
  39. procesio_cli/agents/procesio/__init__.py +0 -0
  40. procesio_cli/agents/procesio/agent.yaml +73 -0
  41. procesio_cli/agents/procesio/audit.py +226 -0
  42. procesio_cli/agents/procesio/checklist.py +135 -0
  43. procesio_cli/agents/procesio/context.py +19 -0
  44. procesio_cli/agents/procesio/handlers/__init__.py +0 -0
  45. procesio_cli/agents/procesio/handlers/audit.py +39 -0
  46. procesio_cli/agents/procesio/handlers/checklist.py +34 -0
  47. procesio_cli/agents/procesio/handlers/guidance.py +36 -0
  48. procesio_cli/agents/procesio/handlers/status.py +33 -0
  49. procesio_cli/agents/procesio/handlers/verify.py +39 -0
  50. procesio_cli/agents/procesio/knowledge.py +115 -0
  51. procesio_cli/agents/procesio/main.py +89 -0
  52. procesio_cli/agents/procesio/tests/__init__.py +0 -0
  53. procesio_cli/agents/procesio/tests/conftest.py +62 -0
  54. procesio_cli/agents/procesio/tests/test_audit.py +91 -0
  55. procesio_cli/agents/procesio/tests/test_checklist.py +28 -0
  56. procesio_cli/agents/procesio/tests/test_guidance.py +78 -0
  57. procesio_cli/agents/procesio/tests/test_manifest_sync.py +48 -0
  58. procesio_cli/agents/procesio/tests/test_verify.py +134 -0
  59. procesio_cli/agents/procesio/tests/test_workspace_scope.py +97 -0
  60. procesio_cli/agents/procesio/verifylib.py +222 -0
  61. procesio_cli/dashboard/README.md +117 -0
  62. procesio_cli/dashboard/__init__.py +18 -0
  63. procesio_cli/dashboard/serve.py +98 -0
  64. procesio_cli/dashboard/server/__init__.py +1 -0
  65. procesio_cli/dashboard/server/config_schemas.py +92 -0
  66. procesio_cli/dashboard/server/google.py +103 -0
  67. procesio_cli/dashboard/server/handler.py +160 -0
  68. procesio_cli/dashboard/server/inventory.py +213 -0
  69. procesio_cli/dashboard/server/jobs.py +118 -0
  70. procesio_cli/dashboard/server/llmtest.py +181 -0
  71. procesio_cli/dashboard/server/procesio_env.py +94 -0
  72. procesio_cli/dashboard/server/routes.py +74 -0
  73. procesio_cli/dashboard/server/runner.py +150 -0
  74. procesio_cli/dashboard/server/security.py +29 -0
  75. procesio_cli/dashboard/server/setup.py +211 -0
  76. procesio_cli/dashboard/server/validate.py +152 -0
  77. procesio_cli/dashboard/tests/conftest.py +16 -0
  78. procesio_cli/dashboard/tests/test_dashboard.py +225 -0
  79. procesio_cli/dashboard/tests/test_procesio_env.py +159 -0
  80. procesio_cli/dashboard/web/actions.js +274 -0
  81. procesio_cli/dashboard/web/api.js +79 -0
  82. procesio_cli/dashboard/web/app.js +385 -0
  83. procesio_cli/dashboard/web/copilot.js +72 -0
  84. procesio_cli/dashboard/web/google.js +121 -0
  85. procesio_cli/dashboard/web/index.html +67 -0
  86. procesio_cli/dashboard/web/procesio_env.js +187 -0
  87. procesio_cli/dashboard/web/styles.css +207 -0
  88. procesio_cli/registry.py +370 -0
  89. procesio_cli/scripts/build-router.py +249 -0
  90. procesio_cli/scripts/build-tool-skill.py +202 -0
  91. procesio_cli/scripts/check-requirements.py +131 -0
  92. procesio_cli/scripts/check-skill-governance.py +174 -0
  93. procesio_cli/scripts/evaluate-skill-routing.py +217 -0
  94. procesio_cli/scripts/evaluate-skills.py +316 -0
  95. procesio_cli/scripts/get-skill.py +122 -0
  96. procesio_cli/scripts/list-skills.py +68 -0
  97. procesio_cli/scripts/list-tools.py +73 -0
  98. procesio_cli/scripts/run-agent.py +59 -0
  99. procesio_cli/scripts/run-tool.py +123 -0
  100. procesio_cli/scripts/secret_scan.py +584 -0
  101. procesio_cli/scripts/set-credential.py +126 -0
  102. procesio_cli/scripts/validate-skills.py +530 -0
  103. procesio_cli/skills/PORTFOLIO.md +134 -0
  104. procesio_cli/skills/__init__.py +6 -0
  105. procesio_cli/skills/agent-skill-engineer/SKILL.md +226 -0
  106. procesio_cli/skills/agent-skill-engineer/evals/evals.json +422 -0
  107. procesio_cli/skills/agent-skill-engineer/references/authoring-standard.md +178 -0
  108. procesio_cli/skills/agent-skill-engineer/references/decision-framework.md +107 -0
  109. procesio_cli/skills/agent-skill-engineer/references/domain-evidence-protocol.md +248 -0
  110. procesio_cli/skills/agent-skill-engineer/references/evaluation-standard.md +191 -0
  111. procesio_cli/skills/agent-skill-engineer/references/expert-lenses.md +167 -0
  112. procesio_cli/skills/agent-skill-engineer/references/field-gate-standard.md +231 -0
  113. procesio_cli/skills/agent-skill-engineer/references/optimization-protocol.md +233 -0
  114. procesio_cli/skills/agent-skill-engineer/references/optimizer-contract.md +268 -0
  115. procesio_cli/skills/agent-skill-engineer/references/portability-standard.md +99 -0
  116. procesio_cli/skills/agent-skill-engineer/references/research-basis.md +128 -0
  117. procesio_cli/skills/agent-skill-engineer/references/review-standard.md +143 -0
  118. procesio_cli/skills/agent-skill-engineer/scripts/audit_skill.py +959 -0
  119. procesio_cli/skills/agent-skill-engineer/scripts/optimize_skill.py +891 -0
  120. procesio_cli/skills/agent-skill-engineer/scripts/scaffold_skill.py +397 -0
  121. procesio_cli/skills/evals/baseline-catalog.json +14 -0
  122. procesio_cli/skills/evals/baseline-routing-v2.json +38 -0
  123. procesio_cli/skills/evals/baseline.json +37 -0
  124. procesio_cli/skills/evals/behavioral.json +367 -0
  125. procesio_cli/skills/evals/field-boundary-development-v1.json +126 -0
  126. procesio_cli/skills/evals/field-closeout-correction-development-v1.json +23 -0
  127. procesio_cli/skills/evals/field-closeout-development-v1.json +89 -0
  128. procesio_cli/skills/evals/portfolio-pressure-training-v1.json +83 -0
  129. procesio_cli/skills/evals/routing.json +363 -0
  130. procesio_cli/skills/evals/validation-baseline.json +4 -0
  131. procesio_cli/skills/procesio-cli/SKILL.md +134 -0
  132. procesio_cli/skills/procesio-cli/evals/evals.json +111 -0
  133. procesio_cli/skills/procesio-cli/evals/workflows.json +16 -0
  134. procesio_cli/skills/procesio-cli/references/connector-lifecycle.md +47 -0
  135. procesio_cli/skills/procesio-cli/references/credentials-admin.md +113 -0
  136. procesio_cli/skills/procesio-cli/references/data-verification.md +71 -0
  137. procesio_cli/skills/procesio-cli/references/documents-files.md +44 -0
  138. procesio_cli/skills/procesio-cli/references/form-e2e.md +57 -0
  139. procesio_cli/skills/procesio-cli/references/operation-contract.md +138 -0
  140. procesio_cli/skills/procesio-cli/references/process-debugging.md +65 -0
  141. procesio_cli/skills/procesio-cli/references/process-lifecycle.md +88 -0
  142. procesio_cli/skills/procesio-cli/references/schedules-webhooks.md +58 -0
  143. procesio_cli/skills/procesio-cli/references/transport-environments.md +53 -0
  144. procesio_cli/skills/procesio-cli-maintainer/SKILL.md +84 -0
  145. procesio_cli/skills/procesio-cli-maintainer/evals/evals.json +116 -0
  146. procesio_cli/skills/procesio-cli-maintainer/references/change-contract.md +34 -0
  147. procesio_cli/skills/procesio-cli-maintainer/references/mcp-compatibility.md +13 -0
  148. procesio_cli/skills/procesio-cli-maintainer/references/skill-authoring.md +51 -0
  149. procesio_cli/skills/procesio-platform-advisor/SKILL.md +82 -0
  150. procesio_cli/skills/procesio-platform-advisor/evals/evals.json +116 -0
  151. procesio_cli/skills/procesio-platform-advisor/references/capability-map.md +22 -0
  152. procesio_cli/skills/procesio-platform-advisor/references/fit-framework.md +35 -0
  153. procesio_cli/skills/procesio-platform-advisor/references/freshness-policy.md +25 -0
  154. procesio_cli/skills/procesio-platform-advisor/references/sizing-method.md +70 -0
  155. procesio_cli/skills/procesio-platform-advisor/scripts/estimate_capacity.py +99 -0
  156. procesio_cli/skills/procesio-setup/SKILL.md +180 -0
  157. procesio_cli/skills/sql-server-optimizer/SKILL.md +86 -0
  158. procesio_cli/skills/sql-server-optimizer/evals/evals.json +116 -0
  159. procesio_cli/skills/sql-server-optimizer/references/db-context.md +44 -0
  160. procesio_cli/skills/sql-server-optimizer/references/generic-mode.md +32 -0
  161. procesio_cli/skills/sql-server-optimizer/references/procesio-mode.md +40 -0
  162. procesio_cli/skills/sql-server-optimizer/references/sql-rules.md +43 -0
  163. procesio_cli/skills/sql-server-optimizer/scripts/export-indexes.sql +178 -0
  164. procesio_cli/skills/sql-server-optimizer/scripts/export-procs-and-functions.sql +118 -0
  165. procesio_cli/skills/sql-server-optimizer/scripts/export-tables.sql +367 -0
  166. procesio_cli/skills/tests/__init__.py +0 -0
  167. procesio_cli/skills/tests/test_agent_skill_engineer.py +240 -0
  168. procesio_cli/skills/tests/test_auth_failure_stop.py +25 -0
  169. procesio_cli/skills/tests/test_capacity_estimator.py +85 -0
  170. procesio_cli/skills/tests/test_field_boundary_learning.py +100 -0
  171. procesio_cli/skills/tests/test_field_closeout_learning.py +123 -0
  172. procesio_cli/skills/tests/test_field_gate_standard.py +76 -0
  173. procesio_cli/skills/tests/test_operational_playbooks.py +51 -0
  174. procesio_cli/skills/tests/test_portfolio_pressure_training.py +35 -0
  175. procesio_cli/skills/tests/test_process_lifecycle_single_run.py +25 -0
  176. procesio_cli/skills/tests/test_skill_evaluator.py +67 -0
  177. procesio_cli/skills/tests/test_skill_optimizer.py +473 -0
  178. procesio_cli/skills/tests/test_skill_portfolio_review.py +70 -0
  179. procesio_cli/skills/tests/test_skill_release_binding.py +204 -0
  180. procesio_cli/skills/tests/test_skill_routing.py +74 -0
  181. procesio_cli/skills/tests/test_skill_scaffold_v2.py +116 -0
  182. procesio_cli/skills/tests/test_validate_skills.py +115 -0
  183. procesio_cli/tools/__init__.py +0 -0
  184. procesio_cli/tools/_lib/README.md +119 -0
  185. procesio_cli/tools/_lib/__init__.py +0 -0
  186. procesio_cli/tools/_lib/accounting.py +120 -0
  187. procesio_cli/tools/_lib/contacts.py +544 -0
  188. procesio_cli/tools/_lib/creds.py +83 -0
  189. procesio_cli/tools/_lib/creds_backends.py +578 -0
  190. procesio_cli/tools/_lib/dbprofiles.py +147 -0
  191. procesio_cli/tools/_lib/dbquery.py +286 -0
  192. procesio_cli/tools/_lib/dbschema.py +225 -0
  193. procesio_cli/tools/_lib/io.py +54 -0
  194. procesio_cli/tools/_lib/manifest.py +297 -0
  195. procesio_cli/tools/_lib/skill_release.py +127 -0
  196. procesio_cli/tools/_lib/skill_resources.py +118 -0
  197. procesio_cli/tools/_lib/userdata.py +228 -0
  198. procesio_cli/tools/_lib/webserialize/__init__.py +16 -0
  199. procesio_cli/tools/_lib/webserialize/admin.py +61 -0
  200. procesio_cli/tools/_lib/webserialize/client.py +264 -0
  201. procesio_cli/tools/_lib/webserialize/config.py +96 -0
  202. procesio_cli/tools/_lib/webserialize/errors.py +27 -0
  203. procesio_cli/tools/_lib/webserialize/framing.py +45 -0
  204. procesio_cli/tools/_lib/webserialize/registry.py +47 -0
  205. procesio_cli/tools/_lib/webserialize/runtime.py +61 -0
  206. procesio_cli/tools/_lib/webserialize/server.py +510 -0
  207. procesio_cli/tools/_lib/websession.py +194 -0
  208. procesio_cli/tools/connector-builder/CONNECTOR-BUILDER-API-NOTES.md +91 -0
  209. procesio_cli/tools/connector-builder/README.md +101 -0
  210. procesio_cli/tools/connector-builder/SKILL.md +248 -0
  211. procesio_cli/tools/connector-builder/__init__.py +7 -0
  212. procesio_cli/tools/connector-builder/actiondef.py +24 -0
  213. procesio_cli/tools/connector-builder/client.py +251 -0
  214. procesio_cli/tools/connector-builder/errors.py +44 -0
  215. procesio_cli/tools/connector-builder/gen_manifest.py +142 -0
  216. procesio_cli/tools/connector-builder/handlers/__init__.py +1 -0
  217. procesio_cli/tools/connector-builder/handlers/admin.py +182 -0
  218. procesio_cli/tools/connector-builder/handlers/auth.py +74 -0
  219. procesio_cli/tools/connector-builder/handlers/builds.py +396 -0
  220. procesio_cli/tools/connector-builder/handlers/common.py +104 -0
  221. procesio_cli/tools/connector-builder/handlers/files.py +111 -0
  222. procesio_cli/tools/connector-builder/handlers/raw.py +38 -0
  223. procesio_cli/tools/connector-builder/handlers/telemetry.py +39 -0
  224. procesio_cli/tools/connector-builder/main.py +94 -0
  225. procesio_cli/tools/connector-builder/tests/conftest.py +146 -0
  226. procesio_cli/tools/connector-builder/tests/test_cb_client.py +86 -0
  227. procesio_cli/tools/connector-builder/tests/test_cb_dispatch.py +105 -0
  228. procesio_cli/tools/connector-builder/tests/test_cb_manifest_sync.py +76 -0
  229. procesio_cli/tools/connector-builder/tests/test_cb_wait.py +123 -0
  230. procesio_cli/tools/connector-builder/tool.yaml +671 -0
  231. procesio_cli/tools/framework-map/.gitattributes +2 -0
  232. procesio_cli/tools/framework-map/README.md +98 -0
  233. procesio_cli/tools/framework-map/SKILL.md +30 -0
  234. procesio_cli/tools/framework-map/app.js +188 -0
  235. procesio_cli/tools/framework-map/fm_builder.py +476 -0
  236. procesio_cli/tools/framework-map/fm_catalog.py +19 -0
  237. procesio_cli/tools/framework-map/fm_ro_catalog.py +94 -0
  238. procesio_cli/tools/framework-map/fm_strings.py +101 -0
  239. procesio_cli/tools/framework-map/main.py +95 -0
  240. procesio_cli/tools/framework-map/styles.css +214 -0
  241. procesio_cli/tools/framework-map/tests/conftest.py +33 -0
  242. procesio_cli/tools/framework-map/tests/test_fm_build.py +126 -0
  243. procesio_cli/tools/framework-map/tests/test_fm_manifest_sync.py +63 -0
  244. procesio_cli/tools/framework-map/tests/test_fm_store_tree.py +75 -0
  245. procesio_cli/tools/framework-map/tool.yaml +61 -0
  246. procesio_cli/tools/mysql/MOVED-TO-CENTRAL.md +29 -0
  247. procesio_cli/tools/mysql/README.md +196 -0
  248. procesio_cli/tools/mysql/SKILL.md +37 -0
  249. procesio_cli/tools/mysql/__init__.py +0 -0
  250. procesio_cli/tools/mysql/connection.py +191 -0
  251. procesio_cli/tools/mysql/main.py +487 -0
  252. procesio_cli/tools/mysql/profiles.template.json +1 -0
  253. procesio_cli/tools/mysql/schema.py +434 -0
  254. procesio_cli/tools/mysql/tests/__init__.py +0 -0
  255. procesio_cli/tools/mysql/tests/conftest.py +21 -0
  256. procesio_cli/tools/mysql/tests/test_manifest_sync.py +68 -0
  257. procesio_cli/tools/mysql/tests/test_mysql.py +201 -0
  258. procesio_cli/tools/mysql/tests/test_mysql_schema.py +337 -0
  259. procesio_cli/tools/mysql/tool.yaml +112 -0
  260. procesio_cli/tools/procesio/DTO-SUBTOOLS-NOTE.md +360 -0
  261. procesio_cli/tools/procesio/FORM-DEV-GUIDE/00-INDEX.md +67 -0
  262. procesio_cli/tools/procesio/FORM-DEV-GUIDE/01-ANATOMY.md +209 -0
  263. procesio_cli/tools/procesio/FORM-DEV-GUIDE/02-CODE-INJECTION.md +309 -0
  264. procesio_cli/tools/procesio/FORM-DEV-GUIDE/03-DOM-CONTRACT.md +370 -0
  265. procesio_cli/tools/procesio/FORM-DEV-GUIDE/04-INTERACTION-RECIPES.md +600 -0
  266. procesio_cli/tools/procesio/FORM-DEV-GUIDE/05-STEPPER-AND-MOTION.md +426 -0
  267. procesio_cli/tools/procesio/FORM-DEV-GUIDE/06-PROCESS-INTEGRATION.md +347 -0
  268. procesio_cli/tools/procesio/FORM-DEV-GUIDE/07-DEPLOY-WORKFLOW.md +294 -0
  269. procesio_cli/tools/procesio/FORM-DEV-GUIDE/08-PITFALLS.md +569 -0
  270. procesio_cli/tools/procesio/FORM-DEV-GUIDE/09-NAVIGATION-AND-HOSTING.md +308 -0
  271. procesio_cli/tools/procesio/PHASE4-E2E-NOTES.md +594 -0
  272. procesio_cli/tools/procesio/PROCESIO-API-CORRECTIONS.md +295 -0
  273. procesio_cli/tools/procesio/PROCESIO-API-NOTES.md +6976 -0
  274. procesio_cli/tools/procesio/PROCESIO-AUTH-NOTES.md +226 -0
  275. procesio_cli/tools/procesio/PROCESIO-CARD-BUILD-NOTES.md +183 -0
  276. procesio_cli/tools/procesio/PROCESIO-CONNECTORS-NOTES.md +141 -0
  277. procesio_cli/tools/procesio/PROCESIO-CUSTOM-ACTION-NOTES.md +179 -0
  278. procesio_cli/tools/procesio/PROCESIO-DOCS-FIX-REPORT.md +123 -0
  279. procesio_cli/tools/procesio/PROCESIO-ENVIRONMENTS-NOTES.md +94 -0
  280. procesio_cli/tools/procesio/PROCESIO-FE-VALIDATION-NOTES.md +107 -0
  281. procesio_cli/tools/procesio/PROCESIO-FOREACH-NOTES.md +199 -0
  282. procesio_cli/tools/procesio/PROCESIO-FORM-API-HANG-NOTE.md +101 -0
  283. procesio_cli/tools/procesio/PROCESIO-FORM-SUBMISSION-NOTES.md +172 -0
  284. procesio_cli/tools/procesio/PROCESIO-HTML-TO-DOCX-NOTES.md +110 -0
  285. procesio_cli/tools/procesio/PROCESIO-INSTANCE-HISTORY-NOTES.md +242 -0
  286. procesio_cli/tools/procesio/PROCESIO-METERING-NOTES.md +201 -0
  287. procesio_cli/tools/procesio/PROCESIO-NODE-CODE-NOTES.md +279 -0
  288. procesio_cli/tools/procesio/PROCESIO-NODE-MODULE-WHITELIST.md +113 -0
  289. procesio_cli/tools/procesio/PROCESIO-PYTHON-ACTION-NOTES.md +165 -0
  290. procesio_cli/tools/procesio/PROCESIO-QUERY-STORE-NOTES.md +826 -0
  291. procesio_cli/tools/procesio/PROCESIO-RECONCILIATION-PATTERNS.md +104 -0
  292. procesio_cli/tools/procesio/PROCESIO-RESOURCE-MODEL-NOTES.md +1100 -0
  293. procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-CRED-OPTIONALITY.md +45 -0
  294. procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-NOTES.md +252 -0
  295. procesio_cli/tools/procesio/PROCESIO-SQL-ACTIONS-NOTES.md +284 -0
  296. procesio_cli/tools/procesio/PROCESIO-USAGE-GUIDE.md +219 -0
  297. procesio_cli/tools/procesio/README.md +341 -0
  298. procesio_cli/tools/procesio/SCHEDULE-INPUT-SECURITY-NOTES.md +63 -0
  299. procesio_cli/tools/procesio/SKILL.md +694 -0
  300. procesio_cli/tools/procesio/__init__.py +1 -0
  301. procesio_cli/tools/procesio/actiondef.py +27 -0
  302. procesio_cli/tools/procesio/assets/html2docx/html2docx.js +2155 -0
  303. procesio_cli/tools/procesio/auth.py +354 -0
  304. procesio_cli/tools/procesio/autogen.py +121 -0
  305. procesio_cli/tools/procesio/client.py +355 -0
  306. procesio_cli/tools/procesio/config.py +96 -0
  307. procesio_cli/tools/procesio/data/endpoints.json +2901 -0
  308. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/01-authentication.md +180 -0
  309. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/02-conventions.md +116 -0
  310. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/ANONYMOUS-SURFACE.md +51 -0
  311. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/README.md +104 -0
  312. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/SYMBOL-INDEX.md +444 -0
  313. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/03-auth-users-workspaces.md +731 -0
  314. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/04-processes.md +913 -0
  315. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/05-actions.md +605 -0
  316. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/06-files.md +237 -0
  317. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/07-forms-documents.md +985 -0
  318. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/08-credentials.md +532 -0
  319. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/09-datastore-datatypes.md +830 -0
  320. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/10-custom-urls.md +319 -0
  321. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/11-subscriptions-resources-analytics.md +455 -0
  322. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/12-webhooks-notifications-misc.md +519 -0
  323. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/13-realtime-signalr.md +153 -0
  324. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/99-internal-and-other-services.md +52 -0
  325. procesio_cli/tools/procesio/docs_info/FormBuilder mock.ts +5725 -0
  326. procesio_cli/tools/procesio/docs_info/Procesio Platform Actions.json +30219 -0
  327. procesio_cli/tools/procesio/docs_info/form-config-enums.ts +92 -0
  328. procesio_cli/tools/procesio/docs_info/form-theme.ts +1603 -0
  329. procesio_cli/tools/procesio/docs_info/process-validation-reference-1.md +2739 -0
  330. procesio_cli/tools/procesio/dto/__init__.py +13 -0
  331. procesio_cli/tools/procesio/dto/credential/builder.py +179 -0
  332. procesio_cli/tools/procesio/dto/credential/config.schema.json +19 -0
  333. procesio_cli/tools/procesio/dto/credential/description.md +193 -0
  334. procesio_cli/tools/procesio/dto/credential/fixtures/rest.config.json +11 -0
  335. procesio_cli/tools/procesio/dto/credential/fixtures/rest.dto.json +28 -0
  336. procesio_cli/tools/procesio/dto/credential/fixtures/rest.template.json +44 -0
  337. procesio_cli/tools/procesio/dto/credential/template.dto.json +16 -0
  338. procesio_cli/tools/procesio/dto/data/_refresh.py +147 -0
  339. procesio_cli/tools/procesio/dto/data/action_catalog.json +30825 -0
  340. procesio_cli/tools/procesio/dto/data/action_families.json +55 -0
  341. procesio_cli/tools/procesio/dto/data/platform_types.json +182 -0
  342. procesio_cli/tools/procesio/dto/datatype/builder.py +223 -0
  343. procesio_cli/tools/procesio/dto/datatype/config.schema.json +47 -0
  344. procesio_cli/tools/procesio/dto/datatype/description.md +85 -0
  345. procesio_cli/tools/procesio/dto/datatype/fixtures/customer.config.json +41 -0
  346. procesio_cli/tools/procesio/dto/datatype/fixtures/customer.dto.json +164 -0
  347. procesio_cli/tools/procesio/dto/datatype/template.dto.json +37 -0
  348. procesio_cli/tools/procesio/dto/document/builder.py +193 -0
  349. procesio_cli/tools/procesio/dto/document/config.schema.json +33 -0
  350. procesio_cli/tools/procesio/dto/document/description.md +124 -0
  351. procesio_cli/tools/procesio/dto/document/fixtures/invoice.config.json +16 -0
  352. procesio_cli/tools/procesio/dto/document/fixtures/invoice.dto.json +32 -0
  353. procesio_cli/tools/procesio/dto/document/template.dto.json +14 -0
  354. procesio_cli/tools/procesio/dto/form/FORM-STYLING-NOTES.md +142 -0
  355. procesio_cli/tools/procesio/dto/form/GOLDEN-DRIFT-NOTES.md +72 -0
  356. procesio_cli/tools/procesio/dto/form/RUN-PROCESS-RESULT-NOTES.md +80 -0
  357. procesio_cli/tools/procesio/dto/form/addelement.py +277 -0
  358. procesio_cli/tools/procesio/dto/form/builder.py +1009 -0
  359. procesio_cli/tools/procesio/dto/form/capture_goldens.py +106 -0
  360. procesio_cli/tools/procesio/dto/form/code_cipher.py +67 -0
  361. procesio_cli/tools/procesio/dto/form/config.schema.json +76 -0
  362. procesio_cli/tools/procesio/dto/form/data_shell.json +1 -0
  363. procesio_cli/tools/procesio/dto/form/description.md +346 -0
  364. procesio_cli/tools/procesio/dto/form/elements/approval.json +259 -0
  365. procesio_cli/tools/procesio/dto/form/elements/assignee.json +137 -0
  366. procesio_cli/tools/procesio/dto/form/elements/button.json +125 -0
  367. procesio_cli/tools/procesio/dto/form/elements/chart.json +341 -0
  368. procesio_cli/tools/procesio/dto/form/elements/chat.json +199 -0
  369. procesio_cli/tools/procesio/dto/form/elements/checkbox.json +153 -0
  370. procesio_cli/tools/procesio/dto/form/elements/column.json +77 -0
  371. procesio_cli/tools/procesio/dto/form/elements/columns.json +78 -0
  372. procesio_cli/tools/procesio/dto/form/elements/datetime-input.json +304 -0
  373. procesio_cli/tools/procesio/dto/form/elements/divider.json +54 -0
  374. procesio_cli/tools/procesio/dto/form/elements/dropdown.json +130 -0
  375. procesio_cli/tools/procesio/dto/form/elements/dynamic-table-row.json +253 -0
  376. procesio_cli/tools/procesio/dto/form/elements/file-upload.json +196 -0
  377. procesio_cli/tools/procesio/dto/form/elements/file-viewer.json +169 -0
  378. procesio_cli/tools/procesio/dto/form/elements/heading.json +79 -0
  379. procesio_cli/tools/procesio/dto/form/elements/icon.json +107 -0
  380. procesio_cli/tools/procesio/dto/form/elements/image.json +174 -0
  381. procesio_cli/tools/procesio/dto/form/elements/input.json +206 -0
  382. procesio_cli/tools/procesio/dto/form/elements/list.json +202 -0
  383. procesio_cli/tools/procesio/dto/form/elements/number-input.json +202 -0
  384. procesio_cli/tools/procesio/dto/form/elements/paragraph.json +79 -0
  385. procesio_cli/tools/procesio/dto/form/elements/radiobox.json +174 -0
  386. procesio_cli/tools/procesio/dto/form/elements/section.json +114 -0
  387. procesio_cli/tools/procesio/dto/form/elements/select.json +217 -0
  388. procesio_cli/tools/procesio/dto/form/elements/side-panel.json +146 -0
  389. procesio_cli/tools/procesio/dto/form/elements/signature-pad.json +141 -0
  390. procesio_cli/tools/procesio/dto/form/elements/static-table-row.json +84 -0
  391. procesio_cli/tools/procesio/dto/form/elements/step.json +105 -0
  392. procesio_cli/tools/procesio/dto/form/elements/stepper.json +126 -0
  393. procesio_cli/tools/procesio/dto/form/elements/tab.json +77 -0
  394. procesio_cli/tools/procesio/dto/form/elements/table.json +279 -0
  395. procesio_cli/tools/procesio/dto/form/elements/tabs.json +114 -0
  396. procesio_cli/tools/procesio/dto/form/elements/textarea.json +213 -0
  397. procesio_cli/tools/procesio/dto/form/enum_map.json +68 -0
  398. procesio_cli/tools/procesio/dto/form/fieldpath.py +284 -0
  399. procesio_cli/tools/procesio/dto/form/fixtures/reg.config.json +32 -0
  400. procesio_cli/tools/procesio/dto/form/fixtures/reg.elements.json +638 -0
  401. procesio_cli/tools/procesio/dto/form/sync_from_mock.py +386 -0
  402. procesio_cli/tools/procesio/dto/framework.py +125 -0
  403. procesio_cli/tools/procesio/dto/process/builder.py +1991 -0
  404. procesio_cli/tools/procesio/dto/process/config.schema.json +159 -0
  405. procesio_cli/tools/procesio/dto/process/description.md +218 -0
  406. procesio_cli/tools/procesio/dto/process/fixtures/greet.config.json +32 -0
  407. procesio_cli/tools/procesio/dto/process/fixtures/greet.dto.json +317 -0
  408. procesio_cli/tools/procesio/dto/process/naming.py +305 -0
  409. procesio_cli/tools/procesio/dto/process/normalize.py +74 -0
  410. procesio_cli/tools/procesio/dto/process/template.dto.json +32 -0
  411. procesio_cli/tools/procesio/dto/refdata.py +87 -0
  412. procesio_cli/tools/procesio/dto/registry.py +27 -0
  413. procesio_cli/tools/procesio/dto/webhook/builder.py +142 -0
  414. procesio_cli/tools/procesio/dto/webhook/config.schema.json +25 -0
  415. procesio_cli/tools/procesio/dto/webhook/description.md +92 -0
  416. procesio_cli/tools/procesio/dto/webhook/fixtures/order.config.json +10 -0
  417. procesio_cli/tools/procesio/dto/webhook/fixtures/order.dto.json +25 -0
  418. procesio_cli/tools/procesio/dto/webhook/template.dto.json +14 -0
  419. procesio_cli/tools/procesio/environments.py +264 -0
  420. procesio_cli/tools/procesio/errors.py +166 -0
  421. procesio_cli/tools/procesio/flowmodel/README.md +37 -0
  422. procesio_cli/tools/procesio/flowmodel/__init__.py +14 -0
  423. procesio_cli/tools/procesio/flowmodel/digest.py +223 -0
  424. procesio_cli/tools/procesio/flowmodel/families.py +34 -0
  425. procesio_cli/tools/procesio/flowmodel/fevalidation.py +1098 -0
  426. procesio_cli/tools/procesio/flowmodel/formdigest.py +232 -0
  427. procesio_cli/tools/procesio/flowmodel/inspect.py +78 -0
  428. procesio_cli/tools/procesio/flowmodel/model.py +82 -0
  429. procesio_cli/tools/procesio/flowmodel/nodeparam.py +871 -0
  430. procesio_cli/tools/procesio/flowmodel/reader.py +191 -0
  431. procesio_cli/tools/procesio/flowmodel/sqlparam.py +410 -0
  432. procesio_cli/tools/procesio/form_code_keys.py +50 -0
  433. procesio_cli/tools/procesio/formlint.py +292 -0
  434. procesio_cli/tools/procesio/gen_manifest.py +118 -0
  435. procesio_cli/tools/procesio/handlers/__init__.py +1 -0
  436. procesio_cli/tools/procesio/handlers/auth_actions.py +103 -0
  437. procesio_cli/tools/procesio/handlers/catalog.py +147 -0
  438. procesio_cli/tools/procesio/handlers/common.py +90 -0
  439. procesio_cli/tools/procesio/handlers/customaction_ops.py +146 -0
  440. procesio_cli/tools/procesio/handlers/datastore_ops.py +482 -0
  441. procesio_cli/tools/procesio/handlers/datatype_ops.py +275 -0
  442. procesio_cli/tools/procesio/handlers/dto_actions.py +258 -0
  443. procesio_cli/tools/procesio/handlers/environment_admin.py +146 -0
  444. procesio_cli/tools/procesio/handlers/fevalidate.py +236 -0
  445. procesio_cli/tools/procesio/handlers/files.py +141 -0
  446. procesio_cli/tools/procesio/handlers/flowgraph.py +229 -0
  447. procesio_cli/tools/procesio/handlers/flowlint.py +269 -0
  448. procesio_cli/tools/procesio/handlers/form_chains.py +336 -0
  449. procesio_cli/tools/procesio/handlers/form_code.py +277 -0
  450. procesio_cli/tools/procesio/handlers/form_element.py +199 -0
  451. procesio_cli/tools/procesio/handlers/form_events.py +441 -0
  452. procesio_cli/tools/procesio/handlers/form_update.py +270 -0
  453. procesio_cli/tools/procesio/handlers/formprocess.py +211 -0
  454. procesio_cli/tools/procesio/handlers/generic.py +135 -0
  455. procesio_cli/tools/procesio/handlers/layout.py +137 -0
  456. procesio_cli/tools/procesio/handlers/nodeparams.py +1018 -0
  457. procesio_cli/tools/procesio/handlers/process_layout.py +189 -0
  458. procesio_cli/tools/procesio/handlers/process_naming.py +213 -0
  459. procesio_cli/tools/procesio/handlers/processes.py +416 -0
  460. procesio_cli/tools/procesio/handlers/profile_admin.py +184 -0
  461. procesio_cli/tools/procesio/handlers/resource_ops.py +447 -0
  462. procesio_cli/tools/procesio/handlers/schedules.py +320 -0
  463. procesio_cli/tools/procesio/handlers/sqlactions.py +232 -0
  464. procesio_cli/tools/procesio/handlers/transport.py +463 -0
  465. procesio_cli/tools/procesio/handlers/usageguide.py +222 -0
  466. procesio_cli/tools/procesio/layout/README.md +196 -0
  467. procesio_cli/tools/procesio/layout/__init__.py +11 -0
  468. procesio_cli/tools/procesio/layout/adapter.py +736 -0
  469. procesio_cli/tools/procesio/layout/cycles.py +186 -0
  470. procesio_cli/tools/procesio/layout/dispatch.py +39 -0
  471. procesio_cli/tools/procesio/layout/elk/elk_runner.mjs +50 -0
  472. procesio_cli/tools/procesio/layout/elk/package-lock.json +21 -0
  473. procesio_cli/tools/procesio/layout/elk/package.json +11 -0
  474. procesio_cli/tools/procesio/layout/elk_engine.py +568 -0
  475. procesio_cli/tools/procesio/layout/engine.py +1311 -0
  476. procesio_cli/tools/procesio/layout/report.py +187 -0
  477. procesio_cli/tools/procesio/main.py +179 -0
  478. procesio_cli/tools/procesio/profiles.py +193 -0
  479. procesio_cli/tools/procesio/reliability.py +193 -0
  480. procesio_cli/tools/procesio/sqlformat.py +167 -0
  481. procesio_cli/tools/procesio/swagger.py +51 -0
  482. procesio_cli/tools/procesio/tests/__init__.py +0 -0
  483. procesio_cli/tools/procesio/tests/conftest.py +129 -0
  484. procesio_cli/tools/procesio/tests/test_auth.py +200 -0
  485. procesio_cli/tools/procesio/tests/test_autogen.py +78 -0
  486. procesio_cli/tools/procesio/tests/test_builder_attrpath_sqlbind.py +180 -0
  487. procesio_cli/tools/procesio/tests/test_builder_custom_action_catalog.py +72 -0
  488. procesio_cli/tools/procesio/tests/test_client.py +114 -0
  489. procesio_cli/tools/procesio/tests/test_client_reliability.py +139 -0
  490. procesio_cli/tools/procesio/tests/test_customaction.py +103 -0
  491. procesio_cli/tools/procesio/tests/test_customaction_test.py +80 -0
  492. procesio_cli/tools/procesio/tests/test_cycles.py +69 -0
  493. procesio_cli/tools/procesio/tests/test_datastore.py +378 -0
  494. procesio_cli/tools/procesio/tests/test_datastore_node.py +94 -0
  495. procesio_cli/tools/procesio/tests/test_dispatch.py +170 -0
  496. procesio_cli/tools/procesio/tests/test_document_page_size.py +19 -0
  497. procesio_cli/tools/procesio/tests/test_dto.py +734 -0
  498. procesio_cli/tools/procesio/tests/test_edit_dryrun_preview.py +96 -0
  499. procesio_cli/tools/procesio/tests/test_elk_layout.py +221 -0
  500. procesio_cli/tools/procesio/tests/test_environments.py +214 -0
  501. procesio_cli/tools/procesio/tests/test_fevalidate_gate.py +104 -0
  502. procesio_cli/tools/procesio/tests/test_fevalidation.py +317 -0
  503. procesio_cli/tools/procesio/tests/test_fieldpath_variables.py +87 -0
  504. procesio_cli/tools/procesio/tests/test_files.py +72 -0
  505. procesio_cli/tools/procesio/tests/test_flow_digest.py +202 -0
  506. procesio_cli/tools/procesio/tests/test_flowlint.py +114 -0
  507. procesio_cli/tools/procesio/tests/test_flowmodel.py +158 -0
  508. procesio_cli/tools/procesio/tests/test_form_add_element.py +256 -0
  509. procesio_cli/tools/procesio/tests/test_form_approval_gaps.py +319 -0
  510. procesio_cli/tools/procesio/tests/test_form_auto_names.py +60 -0
  511. procesio_cli/tools/procesio/tests/test_form_chains.py +217 -0
  512. procesio_cli/tools/procesio/tests/test_form_code_actions.py +188 -0
  513. procesio_cli/tools/procesio/tests/test_form_code_keys.py +92 -0
  514. procesio_cli/tools/procesio/tests/test_form_code_style.py +178 -0
  515. procesio_cli/tools/procesio/tests/test_form_delete_element.py +99 -0
  516. procesio_cli/tools/procesio/tests/test_form_element_config.py +141 -0
  517. procesio_cli/tools/procesio/tests/test_form_event_maps.py +135 -0
  518. procesio_cli/tools/procesio/tests/test_form_event_ops.py +376 -0
  519. procesio_cli/tools/procesio/tests/test_form_event_replace.py +86 -0
  520. procesio_cli/tools/procesio/tests/test_form_events.py +92 -0
  521. procesio_cli/tools/procesio/tests/test_form_parity.py +171 -0
  522. procesio_cli/tools/procesio/tests/test_form_select_source.py +74 -0
  523. procesio_cli/tools/procesio/tests/test_form_sync.py +35 -0
  524. procesio_cli/tools/procesio/tests/test_form_update.py +133 -0
  525. procesio_cli/tools/procesio/tests/test_formlint.py +155 -0
  526. procesio_cli/tools/procesio/tests/test_formlint_css_scope.py +38 -0
  527. procesio_cli/tools/procesio/tests/test_formlint_field_names.py +83 -0
  528. procesio_cli/tools/procesio/tests/test_guards.py +110 -0
  529. procesio_cli/tools/procesio/tests/test_hidden_setting_types.py +39 -0
  530. procesio_cli/tools/procesio/tests/test_html2docx_asset.py +132 -0
  531. procesio_cli/tools/procesio/tests/test_key_handle_terminology.py +45 -0
  532. procesio_cli/tools/procesio/tests/test_layout.py +574 -0
  533. procesio_cli/tools/procesio/tests/test_layout_report.py +88 -0
  534. procesio_cli/tools/procesio/tests/test_manifest_sync.py +68 -0
  535. procesio_cli/tools/procesio/tests/test_nodedelete.py +151 -0
  536. procesio_cli/tools/procesio/tests/test_nodeparam.py +826 -0
  537. procesio_cli/tools/procesio/tests/test_normalize.py +70 -0
  538. procesio_cli/tools/procesio/tests/test_payload_docs.py +86 -0
  539. procesio_cli/tools/procesio/tests/test_process_action_naming.py +170 -0
  540. procesio_cli/tools/procesio/tests/test_process_call_api_seed.py +46 -0
  541. procesio_cli/tools/procesio/tests/test_process_ext.py +373 -0
  542. procesio_cli/tools/procesio/tests/test_process_invariants.py +183 -0
  543. procesio_cli/tools/procesio/tests/test_process_layout.py +117 -0
  544. procesio_cli/tools/procesio/tests/test_process_naming.py +188 -0
  545. procesio_cli/tools/procesio/tests/test_process_query_store.py +172 -0
  546. procesio_cli/tools/procesio/tests/test_processinfo_variable.py +56 -0
  547. procesio_cli/tools/procesio/tests/test_profiles.py +127 -0
  548. procesio_cli/tools/procesio/tests/test_put_projects.py +41 -0
  549. procesio_cli/tools/procesio/tests/test_reliability.py +107 -0
  550. procesio_cli/tools/procesio/tests/test_removal_gate.py +95 -0
  551. procesio_cli/tools/procesio/tests/test_resource_ops.py +173 -0
  552. procesio_cli/tools/procesio/tests/test_save_validity.py +207 -0
  553. procesio_cli/tools/procesio/tests/test_schedule_cron_shape.py +111 -0
  554. procesio_cli/tools/procesio/tests/test_schedules.py +309 -0
  555. procesio_cli/tools/procesio/tests/test_sqlconvert.py +234 -0
  556. procesio_cli/tools/procesio/tests/test_sqlformat.py +83 -0
  557. procesio_cli/tools/procesio/tests/test_sqlparam.py +187 -0
  558. procesio_cli/tools/procesio/tests/test_superseded_actions.py +54 -0
  559. procesio_cli/tools/procesio/tests/test_surgical_concurrency.py +156 -0
  560. procesio_cli/tools/procesio/tests/test_tier4.py +123 -0
  561. procesio_cli/tools/procesio/tests/test_transport.py +147 -0
  562. procesio_cli/tools/procesio/tests/test_transport_data_stores.py +168 -0
  563. procesio_cli/tools/procesio/tests/test_transport_mapper_repair.py +150 -0
  564. procesio_cli/tools/procesio/tests/test_transport_webhook_strip.py +253 -0
  565. procesio_cli/tools/procesio/tests/test_usage_guide.py +96 -0
  566. procesio_cli/tools/procesio/tool.yaml +12486 -0
  567. procesio_cli/tools/sqlserver/MOVED-TO-CENTRAL.md +29 -0
  568. procesio_cli/tools/sqlserver/README.md +192 -0
  569. procesio_cli/tools/sqlserver/SKILL.md +37 -0
  570. procesio_cli/tools/sqlserver/SQLSERVER-SCHEMA-NOTES.md +284 -0
  571. procesio_cli/tools/sqlserver/__init__.py +0 -0
  572. procesio_cli/tools/sqlserver/connection.py +242 -0
  573. procesio_cli/tools/sqlserver/main.py +521 -0
  574. procesio_cli/tools/sqlserver/profiles.template.json +1 -0
  575. procesio_cli/tools/sqlserver/schema.py +600 -0
  576. procesio_cli/tools/sqlserver/tests/__init__.py +0 -0
  577. procesio_cli/tools/sqlserver/tests/conftest.py +21 -0
  578. procesio_cli/tools/sqlserver/tests/test_connection.py +75 -0
  579. procesio_cli/tools/sqlserver/tests/test_dbprofiles.py +92 -0
  580. procesio_cli/tools/sqlserver/tests/test_dbquery.py +220 -0
  581. procesio_cli/tools/sqlserver/tests/test_manifest_sync.py +68 -0
  582. procesio_cli/tools/sqlserver/tests/test_sqlserver.py +326 -0
  583. procesio_cli/tools/sqlserver/tests/test_sqlserver_schema.py +488 -0
  584. procesio_cli/tools/sqlserver/tool.yaml +123 -0
  585. procesio_cli/tools/web/README.md +381 -0
  586. procesio_cli/tools/web/SKILL.md +37 -0
  587. procesio_cli/tools/web/WEB-AUTOMATION-NOTES.md +277 -0
  588. procesio_cli/tools/web/__init__.py +21 -0
  589. procesio_cli/tools/web/actiondef.py +24 -0
  590. procesio_cli/tools/web/api.py +444 -0
  591. procesio_cli/tools/web/brokered.py +107 -0
  592. procesio_cli/tools/web/driver.py +839 -0
  593. procesio_cli/tools/web/drivercontract.py +44 -0
  594. procesio_cli/tools/web/errors.py +54 -0
  595. procesio_cli/tools/web/handlers/__init__.py +1 -0
  596. procesio_cli/tools/web/handlers/archive.py +367 -0
  597. procesio_cli/tools/web/handlers/browse.py +182 -0
  598. procesio_cli/tools/web/handlers/contacts.py +74 -0
  599. procesio_cli/tools/web/handlers/sessmgmt.py +120 -0
  600. procesio_cli/tools/web/main.py +128 -0
  601. procesio_cli/tools/web/sessions.py +253 -0
  602. procesio_cli/tools/web/steps.py +162 -0
  603. procesio_cli/tools/web/tests/__init__.py +0 -0
  604. procesio_cli/tools/web/tests/conftest.py +197 -0
  605. procesio_cli/tools/web/tests/test_api.py +330 -0
  606. procesio_cli/tools/web/tests/test_archive.py +190 -0
  607. procesio_cli/tools/web/tests/test_brokered.py +138 -0
  608. procesio_cli/tools/web/tests/test_dispatch.py +132 -0
  609. procesio_cli/tools/web/tests/test_errors.py +60 -0
  610. procesio_cli/tools/web/tests/test_manifest_sync.py +76 -0
  611. procesio_cli/tools/web/tests/test_page_contacts.py +68 -0
  612. procesio_cli/tools/web/tests/test_sessions.py +145 -0
  613. procesio_cli/tools/web/tests/test_steps.py +210 -0
  614. procesio_cli/tools/web/tool.yaml +184 -0
  615. procesio_cli/tools/xlsx/README.md +34 -0
  616. procesio_cli/tools/xlsx/SKILL.md +28 -0
  617. procesio_cli/tools/xlsx/__init__.py +0 -0
  618. procesio_cli/tools/xlsx/main.py +129 -0
  619. procesio_cli/tools/xlsx/reader.py +91 -0
  620. procesio_cli/tools/xlsx/tests/__init__.py +0 -0
  621. procesio_cli/tools/xlsx/tests/conftest.py +39 -0
  622. procesio_cli/tools/xlsx/tests/test_xlsx.py +103 -0
  623. procesio_cli/tools/xlsx/tool.yaml +30 -0
  624. procesio_cli/webplatform/aat_mcp/AAT-MCP-NOTES.md +244 -0
  625. procesio_cli/webplatform/aat_mcp/README.md +78 -0
  626. procesio_cli/webplatform/aat_mcp/bridge.py +705 -0
  627. procesio_cli/webplatform/aat_mcp/chat_server.py +194 -0
  628. procesio_cli/webplatform/aat_mcp/chat_surface.snapshot.json +668 -0
  629. procesio_cli/webplatform/aat_mcp/chat_surface.yaml +372 -0
  630. procesio_cli/webplatform/aat_mcp/gate.py +68 -0
  631. procesio_cli/webplatform/aat_mcp/http_server.py +139 -0
  632. procesio_cli/webplatform/aat_mcp/protocol.py +175 -0
  633. procesio_cli/webplatform/aat_mcp/server.py +306 -0
  634. procesio_cli/webplatform/aat_mcp/tests/conftest.py +8 -0
  635. procesio_cli/webplatform/aat_mcp/tests/test_aat_mcp.py +255 -0
  636. procesio_cli/webplatform/aat_mcp/tests/test_chat_surface.py +247 -0
  637. procesio_cli/webplatform/aat_mcp/tests/test_discovery.py +489 -0
  638. procesio_cli/webplatform/aat_mcp/tests/test_multiuser.py +86 -0
  639. procesio_cli/webplatform/aat_mcp/tests/test_progressive_discovery.py +89 -0
  640. procesio_cli/webplatform/aat_mcp/tests/test_protocol.py +180 -0
  641. procesio_cli/webplatform/aat_mcp/tests/test_skill_discovery.py +23 -0
  642. procesio_cli-0.1.1.dist-info/METADATA +467 -0
  643. procesio_cli-0.1.1.dist-info/RECORD +647 -0
  644. procesio_cli-0.1.1.dist-info/WHEEL +4 -0
  645. procesio_cli-0.1.1.dist-info/entry_points.txt +7 -0
  646. procesio_cli-0.1.1.dist-info/licenses/LICENSE +201 -0
  647. procesio_cli-0.1.1.dist-info/licenses/NOTICE +5 -0
@@ -0,0 +1,489 @@
1
+ """Targeted capability discovery: one action, keyword search, and the size degrade.
2
+
3
+ Why this exists: dumping a big tool's full schema (procesio: ~369 KB / 379 actions)
4
+ is not a large answer, it is NO answer - the driver truncates it to a single-line
5
+ file that read/grep/bash cannot open, and the turn is lost. Measured against real
6
+ transcripts, 27% of all tool calls in an autonomous run were the model guessing
7
+ argument names. These tests pin the four doors that replace the guessing.
8
+
9
+ The registry is faked so the assertions are about behaviour, not about whichever
10
+ tools happen to be installed; one test runs against the real manifests to prove
11
+ the threshold actually trips on the tool that motivated it.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import json
16
+
17
+ import bridge
18
+ import pytest
19
+ import registry
20
+ import server
21
+
22
+
23
+ def _tool(name, actions, description="a tool"):
24
+ return {"name": name, "description": description, "ready": True,
25
+ "missing_secrets": [], "actions": actions, "args": [],
26
+ "routing": {"primary_action": "", "example": ""}}
27
+
28
+
29
+ def _action(name, description="", args=()):
30
+ return {"name": name, "description": description,
31
+ "args": [{"name": a, "type": "string", "required": r,
32
+ "description": ""} for a, r in args]}
33
+
34
+
35
+ FAKE_TOOLS = [
36
+ _tool("bigtool", [
37
+ _action("datastore-create", "Create a Data Store.",
38
+ [("payload", True), ("workspace-id", False)]),
39
+ _action("datastore-update", "Update a Data Store's columns.",
40
+ [("payload", True)]),
41
+ _action("datastore-get-rows", "Read rows from a Data Store.",
42
+ [("id", True)]),
43
+ _action("export", "Export a process as a .procesio bundle.",
44
+ [("process-id", True), ("out", False)]),
45
+ _action("list-processes", "List processes."),
46
+ ]),
47
+ _tool("smalltool", [_action("ping", "Ping.", [("host", True)])]),
48
+ ]
49
+ FAKE_AGENTS = [
50
+ _tool("bigagent", [_action("guidance", "Serve the playbook.", [("topic", False)])]),
51
+ ]
52
+
53
+
54
+ @pytest.fixture(autouse=True)
55
+ def fake_registry(monkeypatch):
56
+ monkeypatch.setattr(bridge, "_scan_registry",
57
+ lambda: (FAKE_TOOLS, FAKE_AGENTS, []))
58
+
59
+
60
+ # --- door 1: one action's schema -----------------------------------------
61
+
62
+ def test_name_plus_action_returns_only_that_action():
63
+ out = bridge.capabilities(name="bigtool", action="datastore-create")
64
+ cap = out["capability"]
65
+ assert cap["name"] == "bigtool"
66
+ assert cap["action"]["name"] == "datastore-create"
67
+ assert [a["name"] for a in cap["action"]["args"]] == ["payload", "workspace-id"]
68
+ assert [a["name"] for a in cap["action"]["args"] if a["required"]] == ["payload"]
69
+ # No sibling actions leak in - that is the whole point.
70
+ assert "export" not in json.dumps(out)
71
+
72
+
73
+ def test_one_action_payload_stays_small():
74
+ out = bridge.capabilities(name="bigtool", action="datastore-create")
75
+ assert len(json.dumps(out)) < 2000
76
+
77
+
78
+ def test_one_action_carries_the_literal_call_shape():
79
+ cap = bridge.capabilities(name="bigtool", action="export")["capability"]
80
+ assert cap["call"]["aat_run_tool"]["tool"] == "bigtool"
81
+ assert cap["call"]["aat_run_tool"]["action"] == "export"
82
+ assert "hyphens" in cap["hint"]
83
+
84
+
85
+ def test_agent_action_names_the_agent_runner():
86
+ cap = bridge.capabilities(name="bigagent", action="guidance")["capability"]
87
+ assert cap["kind"] == "agent"
88
+ assert "aat_run_agent" in cap["call"]
89
+
90
+
91
+ def test_unknown_action_suggests_close_names():
92
+ out = bridge.capabilities(name="bigtool", action="datastore-crate")
93
+ assert out["unknown_action"] == "datastore-crate"
94
+ assert "datastore-create" in out["did_you_mean"]
95
+ assert out["action_count"] == 5
96
+
97
+
98
+ def test_suggestion_survives_word_order_and_plurals():
99
+ """The mistake a model actually makes: right words, wrong order (`credential-list`
100
+ for `list-credentials`). Edit distance alone scores those as far apart."""
101
+ names = ["list-credentials", "credential-test", "credential-get", "run-process"]
102
+ assert bridge._suggest("credential-list", names)[0] == "list-credentials"
103
+ assert bridge._suggest("instances-list", ["list-instances"])[0] == "list-instances"
104
+
105
+
106
+ def test_suggestion_ignores_unrelated_names():
107
+ assert bridge._suggest("datastore-create", ["send-email", "run-process"]) == []
108
+
109
+
110
+ def test_unknown_capability_still_raises():
111
+ with pytest.raises(KeyError):
112
+ bridge.capabilities(name="ghost")
113
+
114
+
115
+ # --- door 2: keyword search ----------------------------------------------
116
+
117
+ def test_search_finds_actions_across_capabilities():
118
+ out = bridge.capabilities(search="datastore")
119
+ names = {m["action"] for m in out["matches"]}
120
+ assert names == {"datastore-create", "datastore-update", "datastore-get-rows"}
121
+ assert all("args" not in m for m in out["matches"]) # compact, not schemas
122
+
123
+
124
+ def test_search_is_and_not_or():
125
+ out = bridge.capabilities(search="datastore rows")
126
+ assert [m["action"] for m in out["matches"]] == ["datastore-get-rows"]
127
+
128
+
129
+ def test_search_matches_description_too():
130
+ out = bridge.capabilities(search="bundle")
131
+ assert [m["action"] for m in out["matches"]] == ["export"]
132
+
133
+
134
+ def test_search_ranks_name_matches_above_description_matches():
135
+ out = bridge.capabilities(search="export")
136
+ assert out["matches"][0]["action"] == "export"
137
+
138
+
139
+ def test_search_can_be_scoped_to_one_capability():
140
+ assert bridge.capabilities(search="guidance", name="bigtool")["count"] == 0
141
+ assert bridge.capabilities(search="guidance", name="bigagent")["count"] == 1
142
+
143
+
144
+ def test_search_can_be_scoped_by_kind():
145
+ out = bridge.capabilities(search="guidance", kind="tool")
146
+ assert out["count"] == 0
147
+
148
+
149
+ def test_search_reports_total_when_capped(monkeypatch):
150
+ out = bridge._search_actions("datastore", limit=2)
151
+ assert len(out["matches"]) == 2
152
+ assert out["total_matches"] == 3
153
+
154
+
155
+ def test_empty_search_is_a_readable_error():
156
+ with pytest.raises(KeyError):
157
+ bridge.capabilities(search=" ")
158
+
159
+
160
+ # --- door 2b: a strict-AND miss relaxes instead of dead-ending -------------
161
+ #
162
+ # A caller's words come from the TARGET system's vocabulary, not ours, so one wrong
163
+ # word must not hide the whole family. Live cost of the empty answer: a search for
164
+ # "form create template" returned 0 because no description says "template"; the run
165
+ # abandoned the curated create action, fell back to the raw HTTP endpoint, tripped
166
+ # the irreversibility gate and blocked on step 0 having built nothing.
167
+
168
+ def test_one_unmatched_word_still_returns_the_family():
169
+ out = bridge.capabilities(search="datastore create template")
170
+ assert out["matches"], "a strict miss must not come back empty"
171
+ assert out["matches"][0]["action"] == "datastore-create"
172
+
173
+
174
+ def test_relaxed_result_says_which_word_it_ignored():
175
+ out = bridge.capabilities(search="datastore create template")
176
+ assert out["relaxed"] is True
177
+ assert out["dropped_terms"] == ["template"]
178
+ assert set(out["matched_terms"]) == {"datastore", "create"}
179
+ assert "template" in out["hint"]
180
+
181
+
182
+ def test_a_result_that_matches_every_word_is_not_marked_relaxed():
183
+ out = bridge.capabilities(search="datastore rows")
184
+ assert "relaxed" not in out
185
+ assert "dropped_terms" not in out
186
+
187
+
188
+ def test_dropped_terms_are_measured_against_the_top_match():
189
+ """Different matches cover different words, so a set-wide calculation reports
190
+ 'relaxed, dropped nothing' — a contradiction that says nothing about the action
191
+ the caller is about to read."""
192
+ out = bridge.capabilities(search="datastore export bundle")
193
+ top = out["matches"][0]
194
+ hay = f"{top['name']}.{top['action']} {top['description']}".lower()
195
+ for term in out["dropped_terms"]:
196
+ assert term not in hay
197
+ for term in out["matched_terms"]:
198
+ assert term in hay
199
+
200
+
201
+ def test_scoping_word_does_not_make_every_action_a_match():
202
+ """Scoped by name, a token equal to the capability is free for all of its actions.
203
+ Left in the scoring, a query whose real words all miss would still score 1
204
+ everywhere and hand back the whole catalog — worse than the empty answer this
205
+ relaxation exists to fix."""
206
+ out = bridge.capabilities(name="bigtool", search="bigtool zzzz qqqq")
207
+ assert out["count"] == 0
208
+ assert out["total_matches"] == 0
209
+ assert "conclusive" in out["hint"].lower()
210
+
211
+
212
+ def test_nothing_matches_at_all_is_conclusive_and_says_so():
213
+ out = bridge.capabilities(search="zzzz qqqq wwww")
214
+ assert out["matches"] == []
215
+ assert "list-actions-catalog" in out["hint"] # points at the other catalog
216
+
217
+
218
+ def test_a_relaxed_search_does_not_lead_with_a_destructive_action(monkeypatch):
219
+ """'generate form' and 'delete form' match the same one word. Offering the
220
+ deletion first is how a near-miss becomes an incident."""
221
+ tools = [_tool("t", [_action("form-delete", "Delete a form."),
222
+ _action("form-create", "Create a form.")])]
223
+ monkeypatch.setattr(bridge, "_scan_registry", lambda: (tools, [], []))
224
+ out = bridge.capabilities(search="form generate")
225
+ assert out["matches"][0]["action"] == "form-create"
226
+ # …but a caller who DID ask to delete still gets it.
227
+ out = bridge.capabilities(search="form delete")
228
+ assert out["matches"][0]["action"] == "form-delete"
229
+
230
+
231
+ def test_a_relaxation_surviving_only_on_the_capability_name_is_conclusive():
232
+ """Unscoped, the tool's name cannot be stripped up front (naming the tool is how you
233
+ narrow there), so a query whose substantive words all miss stays alive on that one
234
+ token and answers with the tool's whole catalog. Live: 405 rows, none of them about
235
+ what was asked."""
236
+ out = bridge.capabilities(search="bigtool nosuchthing")
237
+ assert out["matches"] == []
238
+ assert out["total_matches"] == 0
239
+ assert out["dropped_terms"] == ["nosuchthing"]
240
+ assert "conclusive" in out["hint"].lower()
241
+ assert "list-actions-catalog" in out["hint"]
242
+
243
+
244
+ def test_a_relaxation_that_explains_nothing_says_it_is_too_vague(monkeypatch):
245
+ tools = [_tool("t", [_action(f"form-op-{i}", "About a form.") for i in range(70)])]
246
+ monkeypatch.setattr(bridge, "_scan_registry", lambda: (tools, [], []))
247
+ out = bridge.capabilities(search="form nosuchword")
248
+ assert out["relaxed"] is True
249
+ assert "too vague" in out["hint"].lower()
250
+
251
+
252
+ def test_action_without_name_falls_back_to_search():
253
+ out = bridge.capabilities(action="datastore-create")
254
+ assert out["matches"][0]["action"] == "datastore-create"
255
+ assert out["matches"][0]["name"] == "bigtool"
256
+
257
+
258
+ # --- door 3: the size degrade --------------------------------------------
259
+
260
+ def test_full_schema_returned_when_under_the_limit(monkeypatch):
261
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "100000")
262
+ cap = bridge.capabilities(name="bigtool")["capability"]
263
+ assert "truncated" not in cap
264
+ assert len(cap["actions"]) == 5
265
+ assert isinstance(cap["actions"][0], dict) # full entries, with args
266
+
267
+
268
+ def test_oversized_schema_degrades_to_the_action_index(monkeypatch):
269
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "200")
270
+ cap = bridge.capabilities(name="bigtool")["capability"]
271
+ assert cap["truncated"] is True
272
+ assert cap["action_count"] == 5
273
+ assert cap["actions"] == ["datastore-create", "datastore-update",
274
+ "datastore-get-rows", "export", "list-processes"]
275
+ assert "action='<one of actions>'" in cap["hint"]
276
+ assert "grep" in cap["hint"]
277
+
278
+
279
+ def test_degrade_names_the_sizes_so_the_reason_is_legible(monkeypatch):
280
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "200")
281
+ cap = bridge.capabilities(name="bigtool")["capability"]
282
+ assert "200-byte limit" in cap["reason"]
283
+
284
+
285
+ def test_degrade_drops_the_index_when_even_that_is_too_big(monkeypatch):
286
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "10")
287
+ cap = bridge.capabilities(name="bigtool")["capability"]
288
+ assert "actions" not in cap
289
+ assert "search=" in cap["hint"]
290
+
291
+
292
+ def test_small_tool_is_never_degraded(monkeypatch):
293
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", str(bridge._DEFAULT_MAX_BYTES))
294
+ cap = bridge.capabilities(name="smalltool")["capability"]
295
+ assert "truncated" not in cap
296
+ assert cap["actions"][0]["args"][0]["name"] == "host"
297
+
298
+
299
+ def test_limit_zero_disables_the_degrade(monkeypatch):
300
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "0")
301
+ assert "truncated" not in bridge.capabilities(name="bigtool")["capability"]
302
+
303
+
304
+ def test_bad_limit_env_falls_back_to_the_default(monkeypatch):
305
+ monkeypatch.setenv("AAT_CAPABILITIES_MAX_BYTES", "not-a-number")
306
+ assert bridge._max_bytes() == bridge._DEFAULT_MAX_BYTES
307
+
308
+
309
+ def test_compact_list_is_unchanged_by_any_of_this():
310
+ out = bridge.capabilities()
311
+ assert out["count"] == 3
312
+ assert {c["name"] for c in out["capabilities"]} == {"bigtool", "smalltool", "bigagent"}
313
+
314
+
315
+ # --- door 0: usage errors answer themselves -------------------------------
316
+
317
+ def test_action_help_lists_valid_args():
318
+ help_ = bridge.action_help("bigtool", "datastore-create")
319
+ assert [a["name"] for a in help_["valid_args"]] == ["payload", "workspace-id"]
320
+ assert help_["valid_args"][0]["required"] is True
321
+
322
+
323
+ def test_action_help_suggests_names_for_an_invented_action():
324
+ help_ = bridge.action_help("bigtool", "datastore-crate")
325
+ assert help_["unknown_action"] == "datastore-crate"
326
+ assert "datastore-create" in help_["did_you_mean"]
327
+
328
+
329
+ def test_action_help_is_none_for_an_unknown_capability():
330
+ assert bridge.action_help("ghost", "whatever") is None
331
+
332
+
333
+ def _run_call(tool, action, error_message):
334
+ """Drive server._run with a tool that fails with `error_message`."""
335
+ def fake(target, act, args):
336
+ return {"ok": False, "error": {"code": "invalid_argument",
337
+ "message": error_message}}
338
+ return fake
339
+
340
+
341
+ def test_usage_error_is_enriched_with_the_valid_args(monkeypatch):
342
+ monkeypatch.setattr(server.bridge, "run_tool",
343
+ _run_call("bigtool", "datastore-create",
344
+ "unrecognized arguments: --workspace_id x"))
345
+ payload, is_error = server._run(
346
+ "tool", {"tool": "bigtool", "action": "datastore-create",
347
+ "args": {"workspace_id": "x"}}, confirmed=False)
348
+ assert is_error is True
349
+ assert [a["name"] for a in payload["schema"]["valid_args"]] == ["payload", "workspace-id"]
350
+
351
+
352
+ def test_unknown_action_error_is_enriched_with_did_you_mean(monkeypatch):
353
+ monkeypatch.setattr(server.bridge, "run_tool",
354
+ _run_call("bigtool", "datastore-crate",
355
+ "unknown action: datastore-crate. Known: a, b, c"))
356
+ payload, _ = server._run("tool", {"tool": "bigtool", "action": "datastore-crate"},
357
+ confirmed=False)
358
+ assert "datastore-create" in payload["schema"]["did_you_mean"]
359
+
360
+
361
+ def test_missing_required_arg_error_is_enriched(monkeypatch):
362
+ monkeypatch.setattr(server.bridge, "run_tool",
363
+ _run_call("bigtool", "datastore-create",
364
+ "the following arguments are required: --payload"))
365
+ payload, _ = server._run("tool", {"tool": "bigtool", "action": "datastore-create"},
366
+ confirmed=False)
367
+ assert payload["schema"]["action"] == "datastore-create"
368
+
369
+
370
+ def test_remote_api_error_is_not_enriched(monkeypatch):
371
+ """A 403 from the remote system is real feedback, not a naming problem - adding
372
+ a schema there would just be noise."""
373
+ monkeypatch.setattr(server.bridge, "run_tool",
374
+ _run_call("bigtool", "export", "HTTP 500"))
375
+ payload, _ = server._run("tool", {"tool": "bigtool", "action": "export"},
376
+ confirmed=False)
377
+ assert "schema" not in payload
378
+ assert "hint" in payload
379
+
380
+
381
+ def test_enrichment_never_masks_the_original_error(monkeypatch):
382
+ monkeypatch.setattr(server.bridge, "action_help",
383
+ lambda *a, **k: (_ for _ in ()).throw(RuntimeError("boom")))
384
+ monkeypatch.setattr(server.bridge, "run_tool",
385
+ _run_call("bigtool", "export", "unknown action: nope"))
386
+ payload, is_error = server._run("tool", {"tool": "bigtool", "action": "nope"},
387
+ confirmed=False)
388
+ assert is_error is True
389
+ assert payload["error"]["message"] == "unknown action: nope"
390
+
391
+
392
+ def test_hint_points_at_the_narrow_doors(monkeypatch):
393
+ monkeypatch.setattr(server.bridge, "run_tool",
394
+ _run_call("bigtool", "export", "HTTP 500"))
395
+ payload, _ = server._run("tool", {"tool": "bigtool", "action": "export"},
396
+ confirmed=False)
397
+ assert "action='export'" in payload["hint"]
398
+ assert "search=" in payload["hint"]
399
+
400
+
401
+ # --- the MCP surface ------------------------------------------------------
402
+
403
+ def test_capabilities_schema_advertises_action_and_search():
404
+ resp = server.handle({"jsonrpc": "2.0", "id": 1, "method": "tools/list"})
405
+ caps = next(t for t in resp["result"]["tools"] if t["name"] == "capabilities")
406
+ # `full` trims the NO-NAME listing; the doors below narrow the WITH-NAME lookup.
407
+ assert set(caps["inputSchema"]["properties"]) == {"kind", "name", "action", "search", "full"}
408
+
409
+
410
+ def test_capabilities_call_threads_action_and_search_through():
411
+ resp = server.handle({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
412
+ "params": {"name": "capabilities",
413
+ "arguments": {"search": "datastore rows"}}})
414
+ payload = json.loads(resp["result"]["content"][0]["text"])
415
+ assert payload["matches"][0]["action"] == "datastore-get-rows"
416
+
417
+
418
+ # --- against the real manifests ------------------------------------------
419
+
420
+ @pytest.mark.parametrize("tool_name", ["procesio"])
421
+ def test_real_oversized_tool_degrades_and_stays_usable(monkeypatch, tool_name):
422
+ """The case that motivated all of this: the full schema is ~369 KB, which the
423
+ driver cannot read back. It must come back as an index instead."""
424
+ monkeypatch.undo() # drop the fake registry for this one
425
+ tools = registry.list_tools()
426
+ if not any(t.get("name") == tool_name for t in tools):
427
+ pytest.skip(f"{tool_name} is not registered on this machine")
428
+
429
+ full = bridge.capabilities(name=tool_name)["capability"]
430
+ assert full["truncated"] is True
431
+ assert full["action_count"] > 100
432
+ assert len(json.dumps(full, ensure_ascii=False)) < 60_000
433
+
434
+ # ...and the narrow door still answers, in about a kilobyte.
435
+ one = bridge.capabilities(name=tool_name, action=full["actions"][0])
436
+ assert len(json.dumps(one, ensure_ascii=False)) < 6_000
437
+
438
+
439
+ # --- managed turn: no competing orchestration loop -----------------------
440
+
441
+ def test_orchestrator_drive_refused_during_a_managed_turn(monkeypatch):
442
+ monkeypatch.setattr(bridge.runner, "run_agent",
443
+ lambda *a, **k: (_ for _ in ()).throw(AssertionError("executed!")))
444
+ token = bridge.set_managed_turn(True)
445
+ try:
446
+ res = bridge.run_agent("orchestrator", "drive", {"run-id": "r1"})
447
+ finally:
448
+ bridge.reset_managed_turn(token)
449
+ assert res["ok"] is False
450
+ assert res["refused"]["reason"] == "managed_turn"
451
+ assert "second orchestration loop" in res["refused"]["message"]
452
+
453
+
454
+ def test_orchestrator_drive_allowed_outside_a_managed_turn(monkeypatch):
455
+ monkeypatch.setattr(bridge.runner, "run_agent",
456
+ lambda agent, argv, **k: {"ok": True, "data": {"ran": agent}})
457
+ assert bridge.run_agent("orchestrator", "drive", {"run-id": "r1"})["data"]["ran"] == "orchestrator"
458
+
459
+
460
+ def test_managed_turn_still_allows_the_rest_of_the_orchestrator(monkeypatch):
461
+ """Only the competing DRIVER is refused: intake/route/record stay available so a managed step
462
+ keeps the doctrine and the run ledger."""
463
+ monkeypatch.setattr(bridge.runner, "run_agent",
464
+ lambda agent, argv, **k: {"ok": True, "data": {"argv": argv}})
465
+ token = bridge.set_managed_turn(True)
466
+ try:
467
+ for action in ("intake", "route", "record", "guidance"):
468
+ assert bridge.run_agent("orchestrator", action, {})["ok"] is True
469
+ finally:
470
+ bridge.reset_managed_turn(token)
471
+
472
+
473
+ def test_managed_turn_blocklist_is_configurable(monkeypatch):
474
+ monkeypatch.setenv("AAT_MCP_MANAGED_TURN_BLOCK", "orchestrator:drive,deputy:decide")
475
+ monkeypatch.setattr(bridge.runner, "run_agent",
476
+ lambda *a, **k: {"ok": True, "data": {}})
477
+ token = bridge.set_managed_turn(True)
478
+ try:
479
+ assert bridge.run_agent("deputy", "decide", {})["ok"] is False
480
+ assert bridge.run_agent("deputy", "digest", {})["ok"] is True
481
+ finally:
482
+ bridge.reset_managed_turn(token)
483
+
484
+
485
+ def test_managed_turn_flag_does_not_leak_between_requests(monkeypatch):
486
+ monkeypatch.setattr(bridge.runner, "run_agent", lambda *a, **k: {"ok": True, "data": {}})
487
+ token = bridge.set_managed_turn(True)
488
+ bridge.reset_managed_turn(token)
489
+ assert bridge.run_agent("orchestrator", "drive", {})["ok"] is True
@@ -0,0 +1,86 @@
1
+ """Multi-user isolation seams (spec 08): per-request user threading + per-user
2
+ userdata + per-user file credentials. No real subprocess."""
3
+ from __future__ import annotations
4
+
5
+ import bridge # adds repo root to sys.path
6
+
7
+
8
+ def test_bridge_threads_user_into_subprocess_env(monkeypatch):
9
+ seen = {}
10
+ monkeypatch.delenv("AAT_HOST_RUNNER_URL", raising=False) # force the local path
11
+ monkeypatch.setattr(bridge.runner, "run_tool",
12
+ lambda tool, argv, **k: seen.update(env=k.get("env")) or {"ok": True, "data": {}})
13
+ tok = bridge.set_user("alice")
14
+ try:
15
+ bridge.run_tool("hello-world", None, {"name": "X"})
16
+ assert seen["env"] == {"AAT_USER_ID": "alice"}
17
+ finally:
18
+ bridge.reset_user(tok)
19
+ # after reset -> single-user (no per-user env)
20
+ seen.clear()
21
+ bridge.run_tool("hello-world", None, {"name": "X"})
22
+ assert seen["env"] is None
23
+
24
+
25
+ def test_delegation_forwards_user_header(monkeypatch):
26
+ captured = {}
27
+
28
+ class _Resp:
29
+ def __enter__(self): return self
30
+ def __exit__(self, *a): return False
31
+ def read(self): return b'{"ok": true, "data": {}}'
32
+
33
+ def fake_urlopen(req, timeout=None):
34
+ captured["headers"] = {k.lower(): v for k, v in req.header_items()}
35
+ return _Resp()
36
+
37
+ monkeypatch.setenv("AAT_HOST_RUNNER_URL", "http://host.docker.internal:8904")
38
+ monkeypatch.setenv("AAT_HOST_RUNNER_TOKEN", "rtok")
39
+ monkeypatch.setattr(bridge.urllib.request, "urlopen", fake_urlopen)
40
+ tok = bridge.set_user("bob")
41
+ try:
42
+ bridge.run_tool("web", "get-text", {"url": "https://example.com"})
43
+ finally:
44
+ bridge.reset_user(tok)
45
+ assert captured["headers"].get("x-aat-user") == "bob"
46
+ assert captured["headers"].get("authorization") == "Bearer rtok"
47
+
48
+
49
+ def test_userdata_isolates_per_user(monkeypatch, tmp_path):
50
+ from tools._lib import userdata
51
+ monkeypatch.setenv("AAT_USERDATA_DIR", str(tmp_path))
52
+ monkeypatch.setenv("AAT_USER_ID", "alice")
53
+ a = userdata.base()
54
+ monkeypatch.setenv("AAT_USER_ID", "bob")
55
+ b = userdata.base()
56
+ assert a == tmp_path / "alice"
57
+ assert b == tmp_path / "bob"
58
+ assert a != b
59
+ monkeypatch.delenv("AAT_USER_ID")
60
+ assert userdata.base() == tmp_path # single-user root, unchanged behaviour
61
+
62
+
63
+ def test_userdata_rejects_traversal(monkeypatch, tmp_path):
64
+ from tools._lib import userdata
65
+ monkeypatch.setenv("AAT_USERDATA_DIR", str(tmp_path))
66
+ monkeypatch.setenv("AAT_USER_ID", "../evil")
67
+ # sanitized to a safe single segment under the root - never escapes
68
+ assert tmp_path in userdata.base().parents or userdata.base().parent == tmp_path
69
+
70
+
71
+ def test_file_creds_isolate_per_user(monkeypatch, tmp_path):
72
+ from tools._lib import creds_backends
73
+ (tmp_path / "alice").mkdir()
74
+ (tmp_path / "bob").mkdir()
75
+ (tmp_path / "alice" / "hello__key").write_text("AAA", encoding="utf-8")
76
+ (tmp_path / "bob" / "hello__key").write_text("BBB", encoding="utf-8")
77
+ (tmp_path / "hello__shared").write_text("SHARED", encoding="utf-8")
78
+ monkeypatch.setenv("AAT_SECRETS_DIR", str(tmp_path))
79
+ be = creds_backends.FileSecretBackend()
80
+ monkeypatch.setenv("AAT_USER_ID", "alice")
81
+ assert be.get_optional("hello", "key") == "AAA"
82
+ monkeypatch.setenv("AAT_USER_ID", "bob")
83
+ assert be.get_optional("hello", "key") == "BBB"
84
+ # a secret only in the shared dir resolves for any user (fallback)
85
+ assert be.get_optional("hello", "shared") == "SHARED"
86
+ assert be.get_optional("hello", "missing") is None
@@ -0,0 +1,89 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+
5
+ import bridge
6
+ import server
7
+
8
+
9
+ def _payload(response):
10
+ return json.loads(response["result"]["content"][0]["text"])
11
+
12
+
13
+ def _call(name, arguments):
14
+ return server.handle({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
15
+ "params": {"name": name, "arguments": arguments}})
16
+
17
+
18
+ def test_get_skill_without_resource_preserves_original_operation(monkeypatch):
19
+ monkeypatch.setattr(server.bridge, "get_skill",
20
+ lambda name: {"name": name, "content": "# Skill", "resources": {}})
21
+ response = _call("get_skill", {"name": "demo"})
22
+ assert _payload(response)["content"] == "# Skill"
23
+
24
+
25
+ def test_get_skill_resource_uses_index_path(monkeypatch):
26
+ monkeypatch.setattr(server.bridge, "get_skill_resource",
27
+ lambda name, path: {"name": name, "resource": {"path": path}})
28
+ response = _call("get_skill", {"name": "demo", "resource": "references/guide.md"})
29
+ assert _payload(response)["resource"]["path"] == "references/guide.md"
30
+
31
+
32
+ def test_get_skill_resource_failure_is_structured(monkeypatch):
33
+ def fail(name, path):
34
+ raise ValueError("resource path must stay inside the skill")
35
+ monkeypatch.setattr(server.bridge, "get_skill_resource", fail)
36
+ response = _call("get_skill", {"name": "demo", "resource": "../secret"})
37
+ assert response["result"]["isError"] is True
38
+ assert "stay inside" in _payload(response)["error"]
39
+
40
+
41
+ def test_optional_fields_are_advertised_without_new_tools():
42
+ response = server.handle({"jsonrpc": "2.0", "id": 1, "method": "tools/list"})
43
+ schemas = {t["name"]: t["inputSchema"] for t in response["result"]["tools"]}
44
+ assert len(schemas) == 6
45
+ assert schemas["get_skill"]["required"] == ["name"]
46
+ assert "resource" in schemas["get_skill"]["properties"]
47
+ # capability search is provided by the existing `search` param (see bridge._search_actions);
48
+ # get_skill's resource retrieval adds no new MCP tool.
49
+ assert "search" in schemas["capabilities"]["properties"]
50
+
51
+
52
+ def test_real_installed_skill_and_sql_script_resource():
53
+ response = _call("get_skill", {"name": "sql-server-optimizer"})
54
+ assert response["result"]["isError"] is False
55
+ skill = _payload(response)
56
+ root = bridge.registry.get_skill("sql-server-optimizer").path
57
+ assert skill["content"] == (root / "SKILL.md").read_text(encoding="utf-8")
58
+ # The SQL exporters live directly under scripts/ (the portfolio migration moved
59
+ # them out of the deprecated references/scripts/ nesting), so they surface in the
60
+ # scripts category and retrieve cleanly.
61
+ path = "scripts/export-indexes.sql"
62
+ assert path in skill["resources"]["scripts"]
63
+ result = _call("get_skill", {"name": "sql-server-optimizer", "resource": path})
64
+ assert result["result"]["isError"] is False
65
+ assert _payload(result)["resource"]["content"] == (root / path).read_text(encoding="utf-8")
66
+ assert "content" not in _payload(result)
67
+ # export-tables.sql was converted to UTF-8 in the same migration, so it now reads
68
+ # back cleanly too; UTF-8 rejection is covered by the tmp-fixture test below.
69
+ tables = "scripts/export-tables.sql"
70
+ assert tables in skill["resources"]["scripts"]
71
+ ok = _call("get_skill", {"name": "sql-server-optimizer", "resource": tables})
72
+ assert ok["result"]["isError"] is False
73
+ assert _payload(ok)["resource"]["content"] == (root / tables).read_text(encoding="utf-8")
74
+
75
+
76
+ def test_real_resource_rejections_at_protocol_boundary(monkeypatch, tmp_path):
77
+ root = tmp_path / "demo"
78
+ (root / "assets").mkdir(parents=True)
79
+ (root / "SKILL.md").write_text("---\nname: demo\ndescription: Demo\n---\n# Demo\n")
80
+ (root / "assets" / "binary.bin").write_bytes(b"\xff\xfe")
81
+ (root / "assets" / "large.txt").write_bytes(b"x" * 512_001)
82
+ monkeypatch.setattr(bridge.registry, "SKILLS_DIR", tmp_path)
83
+ for path in ("../outside", "/outside", "", "assets/missing", "assets/binary.bin",
84
+ "assets/large.txt", "assets/" + "x" * 256, "assets/\x00"):
85
+ response = _call("get_skill", {"name": "demo", "resource": path})
86
+ assert response["result"]["isError"] is True, path
87
+ payload = _payload(response)
88
+ assert "error" in payload and "content" not in payload
89
+ assert str(tmp_path) not in payload["error"]