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,444 @@
1
+ """Public Python API for the web tool.
2
+
3
+ Other tools (e.g. the forthcoming ``whatsapp-personal`` tool) and the outreach
4
+ agent should drive saved sessions through THIS module rather than shelling out
5
+ to the CLI. Everything here is importable as::
6
+
7
+ from tools.web import open_session, run_steps, get_text, screenshot
8
+ # or, for the lower-level pieces:
9
+ from tools.web.api import save_session, list_sessions, delete_session
10
+
11
+ Design
12
+ ------
13
+ * ``open_session(name, ...)`` is the workhorse: it loads a saved session's
14
+ storageState and returns a *started* ``PlaywrightDriver``. Use it as a context
15
+ manager so the browser is always torn down::
16
+
17
+ from tools.web import open_session
18
+ with open_session("whatsapp") as d:
19
+ d.goto("https://web.whatsapp.com")
20
+ d.click("div[title='Search']")
21
+ ...
22
+
23
+ * ``run_steps(name, steps, url=...)`` runs a declarative step list (see
24
+ ``steps.py``) end-to-end against a saved session and returns the collected
25
+ JSON-able outputs - convenient for one-shot scripted interactions.
26
+
27
+ * ``get_text`` / ``screenshot`` are thin one-call conveniences.
28
+
29
+ * ``save_session`` is the interactive capture (headed browser + human signal);
30
+ the ``wait_for_signal`` callback is injectable so callers/tests control when
31
+ the state is captured.
32
+
33
+ All functions accept ``driver_factory`` so tests can inject a FakeDriver and run
34
+ without a real browser; production defaults to ``PlaywrightDriver``.
35
+ """
36
+ from __future__ import annotations
37
+
38
+ from typing import Any, Callable
39
+
40
+ from tools.web import sessions
41
+ from tools.web.driver import BrowserDriver, PlaywrightDriver
42
+ from tools.web.errors import UsageError
43
+ from tools.web.steps import run_steps as _interpret_steps
44
+
45
+ # Re-export the metadata-only helpers so callers get one import surface.
46
+ session_path = sessions.session_path
47
+ list_sessions = sessions.list_all
48
+ delete_session = sessions.delete
49
+
50
+
51
+ def _default_factory(*, storage_state=None, headless=True, channel=None,
52
+ user_data_dir=None, extra_args=None):
53
+ return PlaywrightDriver(storage_state=storage_state, headless=headless,
54
+ channel=channel, user_data_dir=user_data_dir,
55
+ extra_args=extra_args)
56
+
57
+
58
+ def open_session(name: str, *, headless: bool = True, channel: str | None = None,
59
+ url: str | None = None, user_data_dir: str | None = None,
60
+ driver_factory: Callable = _default_factory,
61
+ extra_args: list | None = None) -> BrowserDriver:
62
+ """Load a saved session and return a STARTED driver (use as a context mgr).
63
+
64
+ Two modes: a storageState session (default) OR a PERSISTENT profile (for
65
+ IndexedDB-auth sites like WhatsApp Web, or anti-bot-sensitive sites like
66
+ Google — the on-disk profile carries the login, no storageState involved).
67
+ The persistent mode is selected when ``user_data_dir`` is passed explicitly OR
68
+ auto-detected when a ``<name>.profile`` directory exists for the session, so
69
+ the CLI run/get-text/screenshot actions transparently use whichever mode the
70
+ session was saved in. Raises SessionError if a storageState session is
71
+ missing. Navigates to ``url`` first.
72
+ """
73
+ # Auto-detect a persistent profile saved via `save-session --persistent`:
74
+ # prefer it over storageState so a profile session is usable, not write-only.
75
+ if user_data_dir is None and sessions.profile_exists(name):
76
+ user_data_dir = str(sessions.profile_dir(name))
77
+ if user_data_dir is not None:
78
+ driver = driver_factory(storage_state=None, headless=headless,
79
+ channel=channel, user_data_dir=user_data_dir,
80
+ extra_args=extra_args)
81
+ else:
82
+ state = sessions.load_state(name)
83
+ driver = driver_factory(storage_state=state, headless=headless, channel=channel,
84
+ extra_args=extra_args)
85
+ driver.start()
86
+ # Persistent profiles drop SESSION-scoped cookies on close (Chromium never
87
+ # writes them to disk), so a cookie-auth site (e.g. Ryver) reopens logged
88
+ # out. If save-session captured a cookie sidecar, replay it into the fresh
89
+ # context BEFORE navigating so the very first request carries the session.
90
+ if user_data_dir is not None and sessions.cookies_exist(name):
91
+ inject = getattr(driver, "add_cookies", None)
92
+ cookies = sessions.load_cookies(name)
93
+ if cookies and callable(inject):
94
+ inject(cookies)
95
+ if url:
96
+ driver.goto(url)
97
+ return driver
98
+
99
+
100
+ def run_steps(name: str, steps: list[dict], *, url: str | None = None,
101
+ headless: bool = True, channel: str | None = None,
102
+ user_data_dir: str | None = None,
103
+ hold_seconds: int | None = None,
104
+ hold_until_selector: str | None = None,
105
+ hold_until_url_excludes: str | None = None,
106
+ driver_factory: Callable = _default_factory) -> dict:
107
+ """Run a declarative step list against a saved session; return collected
108
+ outputs ``{"session", "results", "screenshots", "final_url"}``.
109
+
110
+ If ``url`` is given it is visited first (equivalent to a leading goto step).
111
+ ``user_data_dir`` selects the persistent-profile mode. The driver is always
112
+ closed before returning.
113
+
114
+ ``hold_seconds`` keeps the HEADED browser open for up to that long after the
115
+ last step, so a human can review what was staged and click the irreversible
116
+ control themselves - the agent never presses Submit. ``hold_until_selector``
117
+ / ``hold_until_url_excludes`` end the hold early once the human has acted.
118
+ A hold that runs out is SUCCESS, not failure: the steps still ran, so the
119
+ result carries ``hold.completed = False`` rather than raising. Adds a
120
+ ``hold`` block to the output; ``final_url`` and ``diagnostics`` are read
121
+ AFTER the hold so they reflect what the human did.
122
+ """
123
+ if hold_seconds is not None and hold_seconds <= 0:
124
+ raise UsageError("--hold-seconds must be a positive number of seconds")
125
+ if hold_seconds is not None and headless:
126
+ raise UsageError("--hold-seconds requires --headed: holding a headless "
127
+ "browser open gives the human nothing to act on")
128
+ if hold_seconds is None and (hold_until_selector or hold_until_url_excludes):
129
+ raise UsageError("--hold-until-selector/--hold-until-url-excludes require "
130
+ "--hold-seconds")
131
+ driver = open_session(name, headless=headless, channel=channel, url=url,
132
+ user_data_dir=user_data_dir, driver_factory=driver_factory)
133
+ try:
134
+ out = _interpret_steps(driver, steps)
135
+ if hold_seconds is not None:
136
+ out["hold"] = _run_hold(driver, hold_seconds, hold_until_selector,
137
+ hold_until_url_excludes)
138
+ # Re-read AFTER the hold: the whole point is what the human did.
139
+ final = _safe_url(driver)
140
+ if final is not None:
141
+ out["final_url"] = final
142
+ out["diagnostics"] = _diagnostics(driver)
143
+ finally:
144
+ _safe_close(driver)
145
+ out["session"] = name
146
+ return out
147
+
148
+
149
+ def get_text(name: str, url: str, *, selector: str | None = None,
150
+ wait: str | None = None, headless: bool = True,
151
+ channel: str | None = None,
152
+ driver_factory: Callable = _default_factory) -> dict:
153
+ """Load a session, navigate to ``url``, return visible text.
154
+
155
+ With ``selector`` returns that element's text; otherwise the whole page body.
156
+ ``wait`` (a selector) is awaited before reading - handy for SPA content.
157
+ Returns ``{"session", "url", "selector", "text", "final_url"}``.
158
+ """
159
+ driver = open_session(name, headless=headless, channel=channel, url=url,
160
+ driver_factory=driver_factory)
161
+ try:
162
+ if wait:
163
+ driver.wait_for(wait)
164
+ text = driver.extract_text(selector)
165
+ final = _safe_url(driver)
166
+ diag = _diagnostics(driver)
167
+ finally:
168
+ _safe_close(driver)
169
+ return {"session": name, "url": url, "selector": selector,
170
+ "text": text, "final_url": final, "diagnostics": diag}
171
+
172
+
173
+ def screenshot(name: str, url: str, out: str, *, full_page: bool = True,
174
+ wait: str | None = None, headless: bool = True,
175
+ channel: str | None = None,
176
+ driver_factory: Callable = _default_factory) -> dict:
177
+ """Load a session, navigate to ``url``, save a screenshot to ``out``.
178
+
179
+ Returns ``{"session", "url", "path", "final_url"}``.
180
+ """
181
+ driver = open_session(name, headless=headless, channel=channel, url=url,
182
+ driver_factory=driver_factory)
183
+ try:
184
+ if wait:
185
+ driver.wait_for(wait)
186
+ path = driver.screenshot(out, full_page=full_page)
187
+ final = _safe_url(driver)
188
+ diag = _diagnostics(driver)
189
+ finally:
190
+ _safe_close(driver)
191
+ return {"session": name, "url": url, "path": path, "final_url": final, "diagnostics": diag}
192
+
193
+
194
+ def render_pdf(html: str, out: str, *, fmt: str = "A4",
195
+ width: str | None = None, height: str | None = None,
196
+ margin: str | None = None,
197
+ driver_factory: Callable = _default_factory) -> dict:
198
+ """Render an HTML string to a PDF file — no session, no navigation.
199
+
200
+ Launches a throwaway headless Chromium (Chromium's ``page.pdf()`` is
201
+ headless-only), sets the page content to ``html``, writes the PDF to ``out``,
202
+ and tears the browser down. Reusable HTML→PDF for deterministic document
203
+ generation (e.g. the invoice-collector reconstructing a Ryver invoice).
204
+ ``width`` + ``height`` give a custom sheet (e.g. a 1000mm x 2000mm roll-up)
205
+ instead of ``fmt``; ``margin`` overrides the default document margins.
206
+ Returns ``{"out": path, "bytes": n}``.
207
+ """
208
+ import os
209
+
210
+ driver = driver_factory(storage_state=None, headless=True)
211
+ driver.start()
212
+ try:
213
+ driver.render_pdf(html, out, fmt=fmt, width=width, height=height, margin=margin)
214
+ finally:
215
+ _safe_close(driver)
216
+ try:
217
+ size = os.path.getsize(out)
218
+ except OSError:
219
+ size = 0
220
+ return {"out": out, "bytes": size}
221
+
222
+
223
+ def save_session(name: str, url: str, *,
224
+ wait_for_signal: Callable[[], Any] | None = None,
225
+ channel: str | None = None, persistent: bool = False,
226
+ wait_seconds: int | None = None,
227
+ wait_until_url_excludes: str | None = None,
228
+ driver_factory: Callable = _default_factory) -> dict:
229
+ """Interactively capture a session.
230
+
231
+ Launches a HEADED browser at ``url``, lets a human log in, then - after
232
+ ``wait_for_signal()`` returns - persists the auth. Two modes:
233
+
234
+ * default: capture the context's storageState to ``sessions/<name>.json``.
235
+ * ``persistent=True``: drive a persistent Chromium profile at
236
+ ``sessions/<name>.profile`` — the login is already saved on disk in that
237
+ dir, so we just close. Use for IndexedDB-auth sites (WhatsApp Web).
238
+
239
+ ``wait_for_signal`` defaults to blocking on a line from stdin (ENTER).
240
+
241
+ ``wait_seconds`` selects a NON-STDIN wait instead: hold the browser open for
242
+ up to that long while the human logs in. Required when an agent launches the
243
+ flow — agent stdin is EOF, so the ENTER wait returns instantly and saves a
244
+ half-authenticated profile (see WEB-AUTOMATION-NOTES.md). With
245
+ ``wait_until_url_excludes`` the wait ends early, as soon as the address bar
246
+ leaves the login host (e.g. ``accounts.google.com``), then settles briefly.
247
+ """
248
+ sessions.validate_name(name)
249
+ if not url:
250
+ raise UsageError("save_session requires a --url to open for login")
251
+ if wait_seconds is not None and wait_seconds <= 0:
252
+ raise UsageError("--wait-seconds must be a positive number of seconds")
253
+ if wait_for_signal is None and wait_seconds is None:
254
+ wait_for_signal = _block_on_enter
255
+
256
+ if persistent:
257
+ profile = sessions.profile_dir(name)
258
+ profile.mkdir(parents=True, exist_ok=True)
259
+ driver = driver_factory(storage_state=None, headless=False,
260
+ channel=channel, user_data_dir=str(profile))
261
+ driver.start()
262
+ cookies_saved = 0
263
+ try:
264
+ driver.goto(url)
265
+ # human logs in; the profile auto-persists to disk
266
+ waited = _run_wait(driver, wait_for_signal, wait_seconds,
267
+ wait_until_url_excludes)
268
+ # Snapshot live cookies (incl. session-scoped ones) BEFORE close.
269
+ # The profile persists localStorage/IndexedDB but NOT session
270
+ # cookies, so this sidecar is the only durable copy for cookie-auth
271
+ # sites. Re-injected by open_session on every subsequent run.
272
+ grab = getattr(driver, "get_cookies", None)
273
+ if callable(grab):
274
+ cookies = grab() or []
275
+ if cookies:
276
+ sessions.write_cookies(name, cookies)
277
+ cookies_saved = len(cookies)
278
+ finally:
279
+ _safe_close(driver)
280
+ out = {"session": name, "profile": str(profile), "url": url,
281
+ "persistent": True, "cookies_saved": cookies_saved}
282
+ out.update(waited)
283
+ return out
284
+
285
+ driver = driver_factory(storage_state=None, headless=False, channel=channel)
286
+ driver.start()
287
+ try:
288
+ driver.goto(url)
289
+ waited = _run_wait(driver, wait_for_signal, wait_seconds,
290
+ wait_until_url_excludes)
291
+ state = driver.storage_state()
292
+ finally:
293
+ _safe_close(driver)
294
+ path = sessions.write_state(name, state)
295
+ out = {"session": name, "path": str(path), "url": url}
296
+ out.update(waited)
297
+ return out
298
+
299
+
300
+ # --- internals ------------------------------------------------------------
301
+
302
+ _POLL_SECONDS = 2 # how often the login poller re-reads the address bar
303
+ _SETTLE_SECONDS = 8 # post-redirect settle so auth cookies land before snapshot
304
+ _HOLD_PROBE_MS = 500 # per-poll selector probe during a human-handoff hold
305
+
306
+
307
+ def _run_wait(driver, wait_for_signal, wait_seconds, url_excludes) -> dict:
308
+ """Hold the browser open while the human logs in.
309
+
310
+ Returns a small report merged into the action output so the caller can tell
311
+ a completed login from a timeout — never trust ``cookies_saved`` for that.
312
+ """
313
+ if wait_seconds is None:
314
+ wait_for_signal()
315
+ return {"waited_for": "enter"}
316
+
317
+ import sys
318
+ import time
319
+
320
+ print(f"\n>>> Browser open. Log in - saving automatically once you are "
321
+ f"through (up to {wait_seconds}s).", file=sys.stderr, flush=True)
322
+
323
+ deadline = time.monotonic() + wait_seconds
324
+ detected = False
325
+ while time.monotonic() < deadline:
326
+ time.sleep(_POLL_SECONDS)
327
+ if not url_excludes:
328
+ continue
329
+ try:
330
+ current = driver.current_url() or ""
331
+ except Exception: # noqa: BLE001 - browser may be mid-navigation
332
+ continue
333
+ if url_excludes not in current:
334
+ detected = True
335
+ break
336
+
337
+ report = {"waited_for": "url" if url_excludes else "timer",
338
+ "login_detected": detected}
339
+ if detected:
340
+ # Let post-redirect cookies/localStorage settle before we snapshot.
341
+ print(">>> Login detected - settling before save...",
342
+ file=sys.stderr, flush=True)
343
+ time.sleep(_SETTLE_SECONDS)
344
+ try:
345
+ report["final_url"] = driver.current_url()
346
+ except Exception: # noqa: BLE001
347
+ pass
348
+ elif url_excludes:
349
+ print(">>> Timed out still on the login host — session NOT confirmed.",
350
+ file=sys.stderr, flush=True)
351
+ return report
352
+
353
+
354
+ def _run_hold(driver, hold_seconds: int, until_selector: str | None,
355
+ until_url_excludes: str | None) -> dict:
356
+ """Hold a headed browser open after the steps so a human can finish the job.
357
+
358
+ Distinct from ``_run_wait`` (which serves save-session's login capture and
359
+ reports ``login_detected``): this one also polls for a SELECTOR, and a
360
+ timeout here is a normal outcome rather than a suspect one - the human is
361
+ allowed to walk away. Returns
362
+ ``{"held_seconds", "completed", "reason"}`` with reason
363
+ ``selector`` | ``url`` | ``timeout``.
364
+
365
+ ``completed`` is ADVISORY, not proof - same caveat as ``login_detected``.
366
+ The authoritative check stays ``final_url`` + ``diagnostics``.
367
+ """
368
+ import sys
369
+ import time
370
+
371
+ print(f"\n>>> Steps done. Browser stays open up to {hold_seconds}s - review "
372
+ f"and complete the action yourself.", file=sys.stderr, flush=True)
373
+
374
+ started = time.monotonic()
375
+ deadline = started + hold_seconds
376
+ reason = "timeout"
377
+ while time.monotonic() < deadline:
378
+ time.sleep(_POLL_SECONDS)
379
+ if until_selector:
380
+ try:
381
+ driver.wait_for(until_selector, timeout=_HOLD_PROBE_MS)
382
+ reason = "selector"
383
+ break
384
+ except Exception: # noqa: BLE001 - not there yet is the normal case
385
+ pass
386
+ if until_url_excludes:
387
+ try:
388
+ current = driver.current_url() or ""
389
+ except Exception: # noqa: BLE001 - may be mid-navigation
390
+ continue
391
+ if until_url_excludes not in current:
392
+ reason = "url"
393
+ break
394
+
395
+ held = round(time.monotonic() - started, 1)
396
+ completed = reason != "timeout"
397
+ if completed:
398
+ print(f">>> Human action detected ({reason}) after {held}s.",
399
+ file=sys.stderr, flush=True)
400
+ else:
401
+ print(f">>> Hold expired after {held}s with no action detected - the "
402
+ f"steps still ran.", file=sys.stderr, flush=True)
403
+ return {"held_seconds": held, "completed": completed, "reason": reason}
404
+
405
+
406
+ def _block_on_enter() -> None:
407
+ import sys
408
+ print(
409
+ "\n>>> Log in to the site in the opened browser window. "
410
+ "When you are fully logged in, return here and press ENTER to save "
411
+ "the session...",
412
+ file=sys.stderr, flush=True,
413
+ )
414
+ try:
415
+ sys.stdin.readline()
416
+ except (EOFError, KeyboardInterrupt):
417
+ pass
418
+
419
+
420
+ def _diagnostics(driver) -> dict:
421
+ """Collect runtime diagnostics (console/page errors, failed/4xx-5xx requests) if the
422
+ driver supports it. Defensive: a driver without diagnostics() (e.g. test FakeDriver)
423
+ yields an empty dict and never breaks the call."""
424
+ fn = getattr(driver, "diagnostics", None)
425
+ try:
426
+ return fn() if callable(fn) else {}
427
+ except Exception: # noqa: BLE001
428
+ return {}
429
+
430
+
431
+ def _safe_close(driver) -> None:
432
+ close = getattr(driver, "close", None)
433
+ if callable(close):
434
+ try:
435
+ close()
436
+ except Exception: # noqa: BLE001
437
+ pass
438
+
439
+
440
+ def _safe_url(driver) -> str | None:
441
+ try:
442
+ return driver.current_url()
443
+ except Exception: # noqa: BLE001
444
+ return None
@@ -0,0 +1,107 @@
1
+ """Routing of the web tool's generic browser actions (run / get-text /
2
+ screenshot) through the serializing broker that OWNS the target session.
3
+
4
+ Why: brokers exist so exactly one process drives a tool's web session at a
5
+ time (tools/_lib/webserialize). But `web run --session whatsapp ...` used to
6
+ open the profile DIRECTLY — an ad-hoc debugging command could race the
7
+ whatsapp broker's warm browser and invalidate the session. So when the target
8
+ session is broker-owned (registry: whatsapp/ryver/fgo/mirro), the web CLI
9
+ translates the action into a step list and submits it to that broker's
10
+ ``web-steps`` op instead; the broker executes it serialized, on its warm
11
+ browser. Unowned sessions (e.g. 'google') keep the direct behavior.
12
+
13
+ Escape hatches: ``--direct``, the owning tool's ``<PREFIX>_DIRECT`` env, or
14
+ ``--channel`` (not carried by the op — a channel run stays in-process).
15
+ Inside a broker's own worker the owning tool's ``<PREFIX>_SERVICE_WORKER``
16
+ env disables routing automatically, so a worker executing web steps can never
17
+ recurse into itself.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ from tools._lib.webserialize import client as ws_client
22
+ from tools._lib.webserialize import registry as ws_registry
23
+ from tools._lib.webserialize.config import BrokerConfig
24
+
25
+ _TAG_KEYS = ("via", "service_queue_wait_ms", "service_fallback")
26
+
27
+
28
+ def eligible(parsed, *, driver_factory, allow_service: bool) -> BrokerConfig | None:
29
+ """The owning broker config when this invocation should route, else None."""
30
+ if not allow_service or driver_factory is not None:
31
+ return None
32
+ if getattr(parsed, "direct", False):
33
+ return None
34
+ if getattr(parsed, "channel", None):
35
+ return None
36
+ session = getattr(parsed, "session", None)
37
+ if not session:
38
+ return None
39
+ cfg = ws_registry.owner_of_session(session)
40
+ if cfg is None or not ws_client.enabled(cfg):
41
+ return None
42
+ return cfg
43
+
44
+
45
+ def route(cfg: BrokerConfig, action: str, parsed, *, dispatch_direct) -> dict:
46
+ steps, url, reshape = _translate(action, parsed)
47
+ result = ws_client.web_steps(
48
+ cfg, parsed.session, steps, url=url,
49
+ headless=not getattr(parsed, "headed", False),
50
+ dispatch_direct=dispatch_direct,
51
+ )
52
+ if not isinstance(result, dict) or result.get("via") == "direct-fallback":
53
+ return result # fallback already ran the real handler; final shape
54
+ return reshape(result)
55
+
56
+
57
+ def _tags(src: dict, dst: dict) -> dict:
58
+ for k in _TAG_KEYS:
59
+ if k in src:
60
+ dst.setdefault(k, src[k])
61
+ return dst
62
+
63
+
64
+ def _translate(action: str, parsed):
65
+ """(steps, url, reshape) for one of the three generic browser actions."""
66
+ if action == "run":
67
+ from tools.web.handlers.browse import _load_steps
68
+ return _load_steps(parsed), parsed.url, lambda r: r
69
+
70
+ if action == "get-text":
71
+ steps: list[dict] = []
72
+ if parsed.wait:
73
+ steps.append({"do": "wait_for", "selector": parsed.wait})
74
+ step: dict = {"do": "extract_text", "name": "text"}
75
+ if parsed.selector:
76
+ step["selector"] = parsed.selector
77
+ steps.append(step)
78
+
79
+ def reshape(r: dict) -> dict:
80
+ return _tags(r, {
81
+ "session": parsed.session, "url": parsed.url,
82
+ "selector": parsed.selector,
83
+ "text": (r.get("results") or {}).get("text", ""),
84
+ "final_url": r.get("final_url"),
85
+ "diagnostics": r.get("diagnostics", {}),
86
+ })
87
+
88
+ return steps, parsed.url, reshape
89
+
90
+ if action == "screenshot":
91
+ steps = []
92
+ if parsed.wait:
93
+ steps.append({"do": "wait_for", "selector": parsed.wait})
94
+ steps.append({"do": "screenshot", "path": parsed.out,
95
+ "full_page": not parsed.viewport_only})
96
+
97
+ def reshape(r: dict) -> dict:
98
+ return _tags(r, {
99
+ "session": parsed.session, "url": parsed.url,
100
+ "path": parsed.out,
101
+ "final_url": r.get("final_url"),
102
+ "diagnostics": r.get("diagnostics", {}),
103
+ })
104
+
105
+ return steps, parsed.url, reshape
106
+
107
+ raise ValueError(f"no broker translation for web action {action!r}")