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,228 @@
1
+ """Single resolver for WHERE user-specific data lives.
2
+
3
+ North star: the framework (tools/, agents/, skills/, scripts/) carries ZERO
4
+ user-specific data. Everything user-specific - config, runtime state, knowledge,
5
+ resources, preferences, decisions, run history, saved sessions - lives under one
6
+ folder, ``context-state-knowledge/`` at the repo root. That folder is never
7
+ git-versioned (see .gitignore) and is safe to wipe: delete it and the framework
8
+ runs clean for a brand-new user.
9
+
10
+ This module is the ONE place that knows that path, so tools AND agents resolve
11
+ user-data locations the same way and a future move needs a single change here.
12
+ Agents already import ``tools._lib`` (creds, io), so this lives here rather than
13
+ in ``agents/_lib`` to be importable by both without a cross-package dependency.
14
+
15
+ Relocatable: set ``AAT_USERDATA_DIR`` to move the whole user-data root to another
16
+ path or laptop with no code change (serves the LLM-agnostic / portable direction).
17
+
18
+ Installed rather than cloned: when this ships inside a wheel there IS no repo root to
19
+ sit beside, so user data goes to the platform's per-user data directory instead. It must
20
+ never land inside the installation: that directory is replaced on upgrade (taking the
21
+ credentials config and run history with it), can need admin rights to write on a
22
+ system-wide install, and is shared by every account on the machine.
23
+
24
+ Layout under the base:
25
+
26
+ context-state-knowledge/
27
+ store.db # SQLite (context-store tool)
28
+ state/<component>/ # per-agent/tool runtime state
29
+ config/<component>/ # per-agent/tool user config
30
+ prompts/<component>/# per-user prompt copies (base+personal, agents/_lib/prompts.py)
31
+ sessions/ # relocated web login profiles
32
+ exports/ # human-readable dumps
33
+
34
+ Pure path resolution + ensure-exists. Seeding docs/DB schema is the job of the
35
+ context-store tool and the curator/orchestrator agents, not this module.
36
+ """
37
+ from __future__ import annotations
38
+
39
+ import os
40
+ import re
41
+ import sys
42
+ from pathlib import Path
43
+
44
+ # tools/_lib/userdata.py -> parents[2] == repo root
45
+ _REPO_ROOT = Path(__file__).resolve().parents[2]
46
+ _ENV_VAR = "AAT_USERDATA_DIR"
47
+ _USER_ENV = "AAT_USER_ID"
48
+ _WORKSPACE_ENV = "AAT_WORKSPACE_ID"
49
+ _DEFAULT_DIRNAME = "context-state-knowledge"
50
+
51
+ _SAFE = re.compile(r"[^0-9A-Za-z._-]+")
52
+
53
+
54
+ def _safe_component(name: str) -> str:
55
+ """Sanitize a component name into a single safe path segment.
56
+
57
+ Prevents path traversal (no separators, no ``..``) so a caller-supplied
58
+ agent/tool name can never escape the user-data root.
59
+ """
60
+ if not name or not str(name).strip():
61
+ raise ValueError("component name must be a non-empty string")
62
+ seg = _SAFE.sub("-", str(name).strip()).strip("-._")
63
+ if not seg or seg in (".", ".."):
64
+ raise ValueError(f"invalid component name: {name!r}")
65
+ return seg
66
+
67
+
68
+ def _is_checkout() -> bool:
69
+ """True when running from a clone rather than an installed package.
70
+
71
+ A checkout carries its own ``pyproject.toml`` beside the tree; a wheel installs the
72
+ tree without it. That is the cheapest honest signal - matching on "site-packages" in
73
+ the path guesses at a layout that varies by installer, platform and editable install.
74
+ """
75
+ return (_REPO_ROOT / "pyproject.toml").is_file()
76
+
77
+
78
+ def _platform_data_dir() -> Path:
79
+ """The per-user data directory, by platform convention. Standard library only."""
80
+ if os.name == "nt":
81
+ base = os.environ.get("LOCALAPPDATA") or r"~\AppData\Local"
82
+ elif sys.platform == "darwin":
83
+ base = "~/Library/Application Support"
84
+ else:
85
+ base = os.environ.get("XDG_DATA_HOME") or "~/.local/share"
86
+ return Path(base).expanduser() / "procesio-cli"
87
+
88
+
89
+ def _root() -> Path:
90
+ override = os.environ.get(_ENV_VAR)
91
+ if override:
92
+ return Path(override).expanduser()
93
+ if _is_checkout():
94
+ return _REPO_ROOT / _DEFAULT_DIRNAME
95
+ return _platform_data_dir()
96
+
97
+
98
+ def current_user() -> str | None:
99
+ """The active user id (``AAT_USER_ID``), sanitized to a single safe path segment,
100
+ or None in single-user mode. The multi-user web platform sets this per request
101
+ (server-established from the authenticated session, never from model output)."""
102
+ uid = os.environ.get(_USER_ENV)
103
+ return _safe_component(uid) if uid and str(uid).strip() else None
104
+
105
+
106
+ def current_workspace() -> str | None:
107
+ """The active workspace id (``AAT_WORKSPACE_ID``), sanitized to a single safe path
108
+ segment, or None. The multi-tenant PROCESIO module sets this per request alongside
109
+ ``AAT_USER_ID`` (server-established from the authenticated session, never from model
110
+ output). Unset = no workspace dimension, exactly the historical single-workspace
111
+ behaviour, so local Claude Code is unaffected. Personal-workspace semantics
112
+ (PROCESIO ``Guid.Empty``) are the caller's concern - this resolver only sees an id."""
113
+ ws = os.environ.get(_WORKSPACE_ENV)
114
+ return _safe_component(ws) if ws and str(ws).strip() else None
115
+
116
+
117
+ def base() -> Path:
118
+ """The user-data root. Honors ``AAT_USERDATA_DIR`` (the root) and ``AAT_USER_ID``
119
+ (a per-user subdir under it, for the multi-user web platform). Defaults to the
120
+ repo's ``context-state-knowledge/``. **Unset AAT_USER_ID = single-user, exactly as
121
+ before** - so local Claude Code is unaffected. Every other resolver here derives
122
+ from ``base()``, so per-user isolation is automatic (store.db, state, config,
123
+ prompts, sessions, schedule, exports all move under the user's subdir). Created on
124
+ first access.
125
+
126
+ **Workspace dimension (``AAT_WORKSPACE_ID``):** when set, a ``ws/<ws>`` segment is
127
+ inserted BEFORE the user segment, so the data root is ``<root>/ws/<ws>/<user>`` -
128
+ isolating per ``(workspace, user)`` for the multi-tenant PROCESIO module. **Unset =
129
+ exactly today's paths** (``<root>`` or ``<root>/<user>``), so nothing local moves."""
130
+ root = _root()
131
+ ws = current_workspace()
132
+ if ws:
133
+ root = root / "ws" / ws
134
+ uid = current_user()
135
+ if uid:
136
+ root = root / uid
137
+ root.mkdir(parents=True, exist_ok=True)
138
+ return root
139
+
140
+
141
+ def store_db_path() -> Path:
142
+ """Path to the SQLite store file (parent ensured, file not created here)."""
143
+ base() # ensure root exists
144
+ return base() / "store.db"
145
+
146
+
147
+ def state_dir(component: str) -> Path:
148
+ """Per-component runtime state dir, e.g. state_dir('email-classifier')."""
149
+ p = base() / "state" / _safe_component(component)
150
+ p.mkdir(parents=True, exist_ok=True)
151
+ return p
152
+
153
+
154
+ def config_dir(component: str) -> Path:
155
+ """Per-component user config dir, e.g. config_dir('mysql')."""
156
+ p = base() / "config" / _safe_component(component)
157
+ p.mkdir(parents=True, exist_ok=True)
158
+ return p
159
+
160
+
161
+ def prompts_dir(component: str, *, create: bool = True) -> Path:
162
+ """Per-agent personal prompt copies live here (base+personal versioning;
163
+ agents/_lib/prompts.py). Wipe = agents fall back to their framework base
164
+ prompts. ``create=False`` for read paths so resolving a prompt never leaves
165
+ an empty dir behind."""
166
+ p = base() / "prompts" / _safe_component(component)
167
+ if create:
168
+ p.mkdir(parents=True, exist_ok=True)
169
+ return p
170
+
171
+
172
+ def sessions_dir() -> Path:
173
+ """Relocated web login profiles / broker state live here."""
174
+ p = base() / "sessions"
175
+ p.mkdir(parents=True, exist_ok=True)
176
+ return p
177
+
178
+
179
+ def exports_dir() -> Path:
180
+ """Human-readable dumps written by the curator live here."""
181
+ p = base() / "exports"
182
+ p.mkdir(parents=True, exist_ok=True)
183
+ return p
184
+
185
+
186
+ def schedule_dir() -> Path:
187
+ """The user's recurring-work schedule (schedule/*.yaml declarative entries +
188
+ machine-owned state.json/log.jsonl). Read and executed by the orchestrator's
189
+ schedule-tick; user data like everything else here - wipe = no scheduled work."""
190
+ p = base() / "schedule"
191
+ p.mkdir(parents=True, exist_ok=True)
192
+ return p
193
+
194
+
195
+ def describe() -> dict:
196
+ """Small status view for orchestrator/curator health reporting."""
197
+ b = base()
198
+ return {
199
+ "base": str(b),
200
+ "overridden": bool(os.environ.get(_ENV_VAR)),
201
+ "env_var": _ENV_VAR,
202
+ "user": current_user(),
203
+ "multi_user": current_user() is not None,
204
+ "workspace": current_workspace(),
205
+ "multi_tenant": current_workspace() is not None,
206
+ "store_db": str(b / "store.db"),
207
+ "store_db_exists": (b / "store.db").exists(),
208
+ }
209
+
210
+
211
+ def scan() -> dict:
212
+ """File counts across the user-data areas. This is how agents detect a fresh
213
+ start: a wiped folder never breaks the framework - it just scans as empty and
214
+ the orchestrator/curator prompt the user to start building (templates live
215
+ beside each component as <name>.template.json; `orchestrator bootstrap` seeds)."""
216
+ b = base()
217
+
218
+ def count(p: Path) -> int:
219
+ return sum(1 for x in p.rglob("*") if x.is_file()) if p.exists() else 0
220
+
221
+ return {
222
+ "store_db_exists": (b / "store.db").exists(),
223
+ "config_files": count(b / "config"),
224
+ "state_files": count(b / "state"),
225
+ "session_files": count(b / "sessions"),
226
+ "export_files": count(b / "exports"),
227
+ "readme_exists": (b / "README.md").exists(),
228
+ }
@@ -0,0 +1,16 @@
1
+ """webserialize — per-tool serializing brokers for persistent web profiles.
2
+
3
+ Two processes driving the same browser profile concurrently corrupt/invalidate
4
+ the web app's session (Chromium SingletonLock). This lib gives each tool ONE
5
+ broker process that owns its profile and executes commands strictly one at a
6
+ time; clients (the tool's own dispatch, and the generic web tool) submit over
7
+ a tiny local JSONL protocol.
8
+
9
+ Reference integration: tools/whatsapp-personal (v0.2.0 originated the pattern,
10
+ now a thin adapter over this lib). Registry of brokers/ports/owned sessions:
11
+ tools/_lib/webserialize/registry.py.
12
+ """
13
+ from tools._lib.webserialize.config import HOST, PROTO, BrokerConfig # noqa: F401
14
+ from tools._lib.webserialize.errors import ( # noqa: F401
15
+ ServiceError, ServiceRemoteError,
16
+ )
@@ -0,0 +1,61 @@
1
+ """The three service-admin actions every broker-backed tool exposes.
2
+
3
+ These are plain functions over a BrokerConfig; each tool wraps them in its own
4
+ ActionDef (needs_driver/needs_client False) so they never route and always
5
+ work — even when the service is wedged.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from tools._lib.webserialize import client, runtime
10
+ from tools._lib.webserialize.config import BrokerConfig
11
+ from tools._lib.webserialize.errors import ServiceError
12
+
13
+
14
+ def service_status(cfg: BrokerConfig) -> dict:
15
+ pong = client.ping(cfg)
16
+ if pong is None:
17
+ return {
18
+ "running": False,
19
+ "tool": cfg.tool,
20
+ "port": cfg.effective_port(),
21
+ "note": "no service is listening; it auto-starts on the next "
22
+ "browser action (or run service-start)",
23
+ "stale_state_file": runtime.read_state(cfg),
24
+ "log": str(cfg.log_path),
25
+ }
26
+ status = client.request_status(cfg) or {}
27
+ status.setdefault("running", True)
28
+ status["port"] = cfg.effective_port()
29
+ status["code_current"] = pong.get("code_stamp") == runtime.code_stamp(cfg)
30
+ if not status["code_current"]:
31
+ status["note"] = ("service runs STALE code (tool edited since it "
32
+ "started); the next routed command restarts it "
33
+ "automatically, or run service-stop + service-start")
34
+ return status
35
+
36
+
37
+ def service_start(cfg: BrokerConfig) -> dict:
38
+ pong = client.ensure_running(cfg)
39
+ if pong is None:
40
+ raise ServiceError(
41
+ f"could not start the {cfg.tool} service; check "
42
+ f"{cfg.spawn_err_path} and {cfg.log_path}"
43
+ )
44
+ status = client.request_status(cfg) or {}
45
+ return {"running": True, "pid": pong.get("pid"),
46
+ "port": cfg.effective_port(), "status": status}
47
+
48
+
49
+ def service_stop(cfg: BrokerConfig, *, wait_s: float = 60) -> dict:
50
+ was_running = client.ping(cfg) is not None
51
+ stopped = client.stop(cfg, wait_s=wait_s)
52
+ out = {"was_running": was_running, "stopped": stopped,
53
+ "tool": cfg.tool, "port": cfg.effective_port()}
54
+ if not stopped:
55
+ out["note"] = ("service did not exit within the wait window "
56
+ "(a long command may be mid-flight); re-run, or check "
57
+ f"{cfg.log_path}")
58
+ else:
59
+ out["note"] = ("profile released — safe to log in "
60
+ "(web save-session) or use --direct")
61
+ return out
@@ -0,0 +1,264 @@
1
+ """Client side of a serializing broker. Every function takes the tool's
2
+ BrokerConfig first; tools call these from their dispatch routing.
3
+
4
+ Safety rules (they matter for message/state-changing commands):
5
+
6
+ * FALLBACK TO DIRECT happens ONLY when the request was never submitted —
7
+ no service answered and one could not be started. Running direct then is
8
+ safe because the failed service never opened a browser.
9
+ * Once a request has been SENT, a lost connection NEVER falls back: the
10
+ command may be mid-flight, and re-running could double-send.
11
+ * A running service built from STALE code (the tool was edited since it
12
+ started) is detected via ``code_stamp`` and transparently restarted.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import os
17
+ import socket
18
+ import subprocess
19
+ import sys
20
+ import time
21
+ from pathlib import Path
22
+
23
+ from tools._lib.webserialize import framing, runtime
24
+ from tools._lib.webserialize.config import HOST, PROTO, FRAMEWORK_ROOT, BrokerConfig
25
+ from tools._lib.webserialize.errors import ServiceError, ServiceRemoteError
26
+
27
+ _CONNECT_TIMEOUT_S = 5
28
+ _SPAWN_WAIT_S = 25
29
+ _STOP_WAIT_S = 60
30
+
31
+
32
+ # --------------------------------------------------------------------------- #
33
+ # Routing decision
34
+ # --------------------------------------------------------------------------- #
35
+ def enabled(cfg: BrokerConfig) -> bool:
36
+ """Routing is ON unless explicitly disabled or we ARE the service worker."""
37
+ if runtime.env_truthy(cfg.direct_env):
38
+ return False
39
+ if runtime.env_truthy(cfg.worker_env):
40
+ return False
41
+ return True
42
+
43
+
44
+ # --------------------------------------------------------------------------- #
45
+ # Wire helpers
46
+ # --------------------------------------------------------------------------- #
47
+ def _request(cfg: BrokerConfig, obj: dict, *, read_timeout: float,
48
+ port: int | None = None) -> dict:
49
+ """Send one framed request, wait for the one framed response.
50
+
51
+ Connect+send failures raise OSError (caller may safely fall back: nothing
52
+ was accepted). After the request is on the wire, read failures raise
53
+ ServiceError (NOT safe to fall back)."""
54
+ port = port or cfg.effective_port()
55
+ s = socket.create_connection((HOST, port), timeout=_CONNECT_TIMEOUT_S)
56
+ try:
57
+ s.sendall(framing.encode(obj)) # OSError here -> not submitted
58
+ s.settimeout(read_timeout)
59
+ try:
60
+ raw = framing.recv_line(s)
61
+ except (OSError, ValueError) as exc:
62
+ raise ServiceError(
63
+ f"lost the {cfg.tool} service mid-request "
64
+ f"({exc.__class__.__name__}: {exc}). The command MAY still be "
65
+ "executing — check `service-status` and the target system "
66
+ "before retrying a state-changing command."
67
+ ) from exc
68
+ if not raw.strip():
69
+ raise ServiceError(
70
+ f"the {cfg.tool} service closed the connection without a "
71
+ "response. The command MAY have executed — verify before retrying."
72
+ )
73
+ return framing.decode(raw)
74
+ finally:
75
+ try:
76
+ s.close()
77
+ except OSError:
78
+ pass
79
+
80
+
81
+ def ping(cfg: BrokerConfig, *, timeout: float = 2.0,
82
+ port: int | None = None) -> dict | None:
83
+ try:
84
+ resp = _request(cfg, {"op": "ping"}, read_timeout=timeout, port=port)
85
+ except (OSError, ServiceError, ValueError):
86
+ return None
87
+ if resp.get("ok") and (resp.get("result") or {}).get("pong"):
88
+ return resp["result"]
89
+ return None
90
+
91
+
92
+ def request_status(cfg: BrokerConfig, *, port: int | None = None) -> dict | None:
93
+ try:
94
+ resp = _request(cfg, {"op": "status"}, read_timeout=10, port=port)
95
+ except (OSError, ServiceError, ValueError):
96
+ return None
97
+ return resp.get("result") if resp.get("ok") else None
98
+
99
+
100
+ def stop(cfg: BrokerConfig, *, wait_s: float = _STOP_WAIT_S,
101
+ port: int | None = None) -> bool:
102
+ """Ask the service to stop; True when it is gone (or was never running)."""
103
+ if ping(cfg, port=port) is None:
104
+ return True
105
+ try:
106
+ _request(cfg, {"op": "stop"}, read_timeout=10, port=port)
107
+ except (OSError, ServiceError, ValueError):
108
+ pass
109
+ deadline = time.time() + wait_s
110
+ while time.time() < deadline:
111
+ if ping(cfg, port=port) is None:
112
+ return True
113
+ time.sleep(0.3)
114
+ return False
115
+
116
+
117
+ # --------------------------------------------------------------------------- #
118
+ # Lifecycle
119
+ # --------------------------------------------------------------------------- #
120
+ def spawn(cfg: BrokerConfig) -> int:
121
+ """Start the tool's service DETACHED. Startup errors land in
122
+ .service/spawn-err.log; runtime logs in service.log."""
123
+ py = runtime.venv_python() or Path(sys.executable)
124
+ cfg.service_dir.mkdir(parents=True, exist_ok=True)
125
+ err = open(cfg.spawn_err_path, "ab")
126
+ kwargs: dict = dict(stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
127
+ stderr=err, close_fds=True, cwd=str(FRAMEWORK_ROOT))
128
+ if os.name == "nt":
129
+ # CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP
130
+ kwargs["creationflags"] = 0x08000000 | 0x00000200
131
+ else:
132
+ kwargs["start_new_session"] = True
133
+ try:
134
+ proc = subprocess.Popen([str(py), str(cfg.service_py)], **kwargs)
135
+ finally:
136
+ err.close()
137
+ return proc.pid
138
+
139
+
140
+ def ensure_running(cfg: BrokerConfig, *, port: int | None = None) -> dict | None:
141
+ """Make sure a CURRENT-code service is up. Returns its ping payload, or
142
+ None when one could not be started (caller falls back to direct)."""
143
+ pong = ping(cfg, port=port)
144
+ if pong is not None:
145
+ stale = (pong.get("proto") != PROTO
146
+ or pong.get("code_stamp") != runtime.code_stamp(cfg))
147
+ if not stale:
148
+ return pong
149
+ # Stale daemon: restart. If it will not die, keep using it (it still
150
+ # serializes correctly; it just runs older code).
151
+ if not stop(cfg, port=port):
152
+ return pong
153
+ try:
154
+ spawn(cfg)
155
+ except OSError:
156
+ return None
157
+ deadline = time.time() + _SPAWN_WAIT_S
158
+ while time.time() < deadline:
159
+ pong = ping(cfg, port=port)
160
+ if pong is not None:
161
+ return pong
162
+ time.sleep(0.25)
163
+ return None
164
+
165
+
166
+ # --------------------------------------------------------------------------- #
167
+ # The calls used by tool dispatchers
168
+ # --------------------------------------------------------------------------- #
169
+ def _timeout_for(cfg: BrokerConfig, parsed) -> float:
170
+ """Generous per-request wait: the action's own waits plus queue allowance
171
+ (other sessions' commands run first). Env override wins."""
172
+ raw = os.environ.get(cfg.timeout_env, "")
173
+ if raw.strip():
174
+ try:
175
+ return float(raw)
176
+ except ValueError:
177
+ pass
178
+ wait_ms = getattr(parsed, "wait", 0) or 0
179
+ reply_ms = getattr(parsed, "timeout", 0) or 0
180
+ est = 120 + 2 * (wait_ms / 1000.0) + (reply_ms / 1000.0)
181
+ return max(900.0, est + 600.0)
182
+
183
+
184
+ def _tag(result, resp: dict, via: str):
185
+ if isinstance(result, dict):
186
+ result.setdefault("via", via)
187
+ if "queue_wait_ms" in resp:
188
+ result.setdefault("service_queue_wait_ms", resp["queue_wait_ms"])
189
+ return result
190
+
191
+
192
+ def _raise_remote(resp: dict):
193
+ err = resp.get("error") or {}
194
+ raise ServiceRemoteError(
195
+ err.get("code") or "error",
196
+ err.get("message") or "service reported an error",
197
+ err.get("details") or {},
198
+ int(resp.get("exit_code") or 1),
199
+ )
200
+
201
+
202
+ def call(cfg: BrokerConfig, action: str, argv: list[str], parsed, *,
203
+ dispatch_direct) -> dict:
204
+ """Run a TOOL ACTION through the broker. ``dispatch_direct(action, argv)``
205
+ is the in-process fallback, used ONLY when nothing was ever submitted."""
206
+ pong = ensure_running(cfg)
207
+ if pong is None:
208
+ result = dispatch_direct(action, argv)
209
+ if isinstance(result, dict):
210
+ result.setdefault("via", "direct-fallback")
211
+ result.setdefault(
212
+ "service_fallback",
213
+ f"the {cfg.tool} serializing service could not be started; "
214
+ f"executed in-process instead (see {cfg.spawn_err_path})")
215
+ return result
216
+ try:
217
+ resp = _request(cfg, {"op": "run", "action": action, "argv": list(argv)},
218
+ read_timeout=_timeout_for(cfg, parsed))
219
+ except OSError as exc:
220
+ # Connect/send failed AFTER a good ping — the service just died and
221
+ # nothing was submitted, so direct is still safe.
222
+ result = dispatch_direct(action, argv)
223
+ if isinstance(result, dict):
224
+ result.setdefault("via", "direct-fallback")
225
+ result.setdefault("service_fallback",
226
+ f"service vanished before accepting the request "
227
+ f"({exc.__class__.__name__}); executed in-process")
228
+ return result
229
+ if resp.get("ok"):
230
+ return _tag(resp.get("result"), resp, "service")
231
+ _raise_remote(resp)
232
+
233
+
234
+ def web_steps(cfg: BrokerConfig, session: str, steps: list, *, url=None,
235
+ headless: bool = True, read_timeout: float | None = None,
236
+ dispatch_direct=None) -> dict:
237
+ """Run a GENERIC web-tool step list through the broker owning ``session``
238
+ (how `web run/get-text/screenshot` stay serialized). Same fallback rules
239
+ as ``call``: ``dispatch_direct()`` (no args) only when never submitted."""
240
+ pong = ensure_running(cfg)
241
+ if pong is None:
242
+ if dispatch_direct is None:
243
+ raise ServiceError(
244
+ f"the {cfg.tool} service (owner of session {session!r}) could "
245
+ f"not be started; see {cfg.spawn_err_path}")
246
+ result = dispatch_direct()
247
+ if isinstance(result, dict):
248
+ result.setdefault("via", "direct-fallback")
249
+ return result
250
+ req = {"op": "web-steps", "session": session, "steps": steps,
251
+ "url": url, "headless": headless}
252
+ try:
253
+ resp = _request(cfg, req, read_timeout=read_timeout or 900.0)
254
+ except OSError:
255
+ if dispatch_direct is None:
256
+ raise ServiceError(
257
+ f"the {cfg.tool} service vanished before accepting the request")
258
+ result = dispatch_direct()
259
+ if isinstance(result, dict):
260
+ result.setdefault("via", "direct-fallback")
261
+ return result
262
+ if resp.get("ok"):
263
+ return _tag(resp.get("result"), resp, "service")
264
+ _raise_remote(resp)
@@ -0,0 +1,96 @@
1
+ """BrokerConfig — everything that parameterizes one tool's serializing broker.
2
+
3
+ One broker per tool, one fixed localhost port per broker (binding the port IS
4
+ the single-instance guard), one `.service/` runtime dir under the tool root.
5
+ The env-var names are derived from ``env_prefix`` so every tool gets the same
6
+ knobs (`<PREFIX>_DIRECT`, `<PREFIX>_SERVICE_PORT`, ...) — for
7
+ ``whatsapp-personal`` the prefix is ``WHATSAPP``, which keeps the original
8
+ variable names working unchanged.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import os
13
+ from dataclasses import dataclass, field
14
+ from pathlib import Path
15
+
16
+ PROTO = 1
17
+ HOST = "127.0.0.1"
18
+
19
+ DEFAULT_IDLE_CLOSE_S = 120 # close the warm browser after this much idle
20
+ DEFAULT_EXIT_IDLE_S = 86400 # exit the service process after this much idle
21
+
22
+ # tools/_lib/webserialize/config.py -> repo root
23
+ FRAMEWORK_ROOT = Path(__file__).resolve().parents[3]
24
+ TOOLS_ROOT = FRAMEWORK_ROOT / "tools"
25
+ LIB_DIR = Path(__file__).resolve().parent
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class BrokerConfig:
30
+ tool: str # registry key, e.g. "whatsapp-personal"
31
+ port: int # fixed default port (env can override)
32
+ env_prefix: str # "WHATSAPP" -> WHATSAPP_DIRECT, ...
33
+ sessions: tuple[str, ...] # persistent-profile session names it OWNS
34
+ code_dirs: tuple[Path, ...] = field(default=()) # *.py dirs for code_stamp
35
+
36
+ # --- paths --------------------------------------------------------------
37
+ @property
38
+ def tool_root(self) -> Path:
39
+ return TOOLS_ROOT / self.tool
40
+
41
+ @property
42
+ def service_py(self) -> Path:
43
+ return self.tool_root / "service.py"
44
+
45
+ @property
46
+ def service_dir(self) -> Path:
47
+ return self.tool_root / ".service"
48
+
49
+ @property
50
+ def state_path(self) -> Path:
51
+ return self.service_dir / "state.json"
52
+
53
+ @property
54
+ def log_path(self) -> Path:
55
+ return self.service_dir / "service.log"
56
+
57
+ @property
58
+ def spawn_err_path(self) -> Path:
59
+ return self.service_dir / "spawn-err.log"
60
+
61
+ # --- env knobs ------------------------------------------------------------
62
+ @property
63
+ def direct_env(self) -> str:
64
+ return f"{self.env_prefix}_DIRECT"
65
+
66
+ @property
67
+ def worker_env(self) -> str:
68
+ return f"{self.env_prefix}_SERVICE_WORKER"
69
+
70
+ @property
71
+ def port_env(self) -> str:
72
+ return f"{self.env_prefix}_SERVICE_PORT"
73
+
74
+ @property
75
+ def timeout_env(self) -> str:
76
+ return f"{self.env_prefix}_SERVICE_TIMEOUT_S"
77
+
78
+ @property
79
+ def idle_close_env(self) -> str:
80
+ return f"{self.env_prefix}_SERVICE_IDLE_S"
81
+
82
+ @property
83
+ def exit_idle_env(self) -> str:
84
+ return f"{self.env_prefix}_SERVICE_EXIT_S"
85
+
86
+ def effective_port(self) -> int:
87
+ raw = os.environ.get(self.port_env, "")
88
+ try:
89
+ return int(raw) if raw.strip() else self.port
90
+ except ValueError:
91
+ return self.port
92
+
93
+ def stamp_dirs(self) -> tuple[Path, ...]:
94
+ """Dirs whose *.py mtimes form the code stamp. The lib itself is always
95
+ included: a webserialize change must restart every broker."""
96
+ return tuple(self.code_dirs) + (LIB_DIR,)