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,111 @@
1
+ """A cron schedule's recurrence block must carry the cron keys and NOTHING else.
2
+
3
+ The defect: `--cron` overlaid the crontab keys on top of whatever recurrence the caller's
4
+ `--payload` already had. That payload is normally cloned from a live schedule (the API's
5
+ own documented advice, because the write body is validated for shape), so it arrives
6
+ carrying the calendar-recurrence fields `every` / `onDay` / `onThe` / `isOnThe` /
7
+ `isWeekendExcluded`. With those still present the create/update is refused with the
8
+ generic
9
+
10
+ [{"statusCode":502,"value":"Invalid request due to missing or incorrect resource
11
+ parameters.","target":"schedules"}]
12
+
13
+ which names no field, so the failure reads as "cron is not supported here" rather than
14
+ "you sent five keys too many". `POST /api/Schedules/validate-crontab` accepts the very
15
+ same expression happily, which makes the wrong conclusion easy to reach.
16
+
17
+ The expected shape below was captured from the designer's own PUT.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import argparse
22
+
23
+ from tools.procesio.handlers import schedules
24
+
25
+
26
+ CRON_ONLY = {"recurrence", "cronExpression", "timeZone", "info", "isEndDate", "startDate",
27
+ "endDate"}
28
+ CALENDAR_ONLY = {"every", "onDay", "onThe", "isOnThe", "isWeekendExcluded"}
29
+
30
+
31
+ def _args(**kw):
32
+ base = {"cron": None, "timezone": None, "recurrence_info": None}
33
+ return argparse.Namespace(**{**base, **kw})
34
+
35
+
36
+ def _legacy_payload() -> dict:
37
+ """A payload cloned from a live MINUTES schedule, as a caller would build one."""
38
+ return {"name": "S", "targetProcess": "p", "processInputs": [],
39
+ "recurrence": {"info": "every 2 minutes", "every": 2, "onDay": 0,
40
+ "onThe": [2, 1], "endDate": "2027-12-31T00:00:00Z",
41
+ "isOnThe": False, "isEndDate": False,
42
+ "startDate": "2026-08-30T06:00:00", "recurrence": 2,
43
+ "isWeekendExcluded": False}}
44
+
45
+
46
+ def test_the_calendar_recurrence_fields_are_dropped():
47
+ body = schedules._apply_cron(_legacy_payload(),
48
+ _args(cron="*/2 * * * *", timezone="Europe/Bucharest"))
49
+ leftover = CALENDAR_ONLY & set(body["recurrence"])
50
+ assert not leftover, (
51
+ f"{sorted(leftover)} survived into a cron recurrence; the API refuses the whole "
52
+ f"body without naming them")
53
+
54
+
55
+ def test_the_block_carries_the_cron_keys():
56
+ body = schedules._apply_cron(_legacy_payload(),
57
+ _args(cron="*/2 * * * *", timezone="Europe/Bucharest"))
58
+ rec = body["recurrence"]
59
+ assert rec["recurrence"] == 8
60
+ assert rec["cronExpression"] == "*/2 * * * *"
61
+ assert rec["timeZone"] == "Europe/Bucharest"
62
+
63
+
64
+ def test_no_key_outside_the_captured_shape_is_emitted():
65
+ body = schedules._apply_cron(_legacy_payload(),
66
+ _args(cron="0 9 * * 1", timezone="UTC"))
67
+ assert set(body["recurrence"]) <= CRON_ONLY
68
+
69
+
70
+ def test_the_activation_start_survives():
71
+ """The only calendar field a cron schedule legitimately keeps."""
72
+ body = schedules._apply_cron(_legacy_payload(), _args(cron="*/5 * * * *"))
73
+ assert body["recurrence"]["startDate"] == "2026-08-30T06:00:00"
74
+
75
+
76
+ def test_an_end_date_is_dropped_unless_the_window_really_ends():
77
+ """isEndDate false with an endDate still set is the shape the designer never sends."""
78
+ body = schedules._apply_cron(_legacy_payload(), _args(cron="*/5 * * * *"))
79
+ assert body["recurrence"]["isEndDate"] is False
80
+ assert "endDate" not in body["recurrence"]
81
+
82
+
83
+ def test_an_end_date_is_kept_when_the_window_does_end():
84
+ payload = _legacy_payload()
85
+ payload["recurrence"]["isEndDate"] = True
86
+ body = schedules._apply_cron(payload, _args(cron="*/5 * * * *"))
87
+ assert body["recurrence"]["endDate"] == "2027-12-31T00:00:00Z"
88
+
89
+
90
+ def test_the_timezone_from_the_payload_is_used_when_no_flag_is_given():
91
+ payload = _legacy_payload()
92
+ payload["recurrence"]["timeZone"] = "Europe/Bucharest"
93
+ body = schedules._apply_cron(payload, _args(cron="*/5 * * * *"))
94
+ assert body["recurrence"]["timeZone"] == "Europe/Bucharest"
95
+
96
+
97
+ def test_an_explicit_label_wins_over_the_payload_one():
98
+ body = schedules._apply_cron(_legacy_payload(),
99
+ _args(cron="*/2 * * * *", recurrence_info="Every 2 minutes"))
100
+ assert body["recurrence"]["info"] == "Every 2 minutes"
101
+
102
+
103
+ def test_everything_outside_the_recurrence_is_untouched():
104
+ body = schedules._apply_cron(_legacy_payload(), _args(cron="*/2 * * * *"))
105
+ assert body["name"] == "S" and body["targetProcess"] == "p"
106
+
107
+
108
+ def test_without_cron_the_payload_passes_through_verbatim():
109
+ payload = _legacy_payload()
110
+ before = dict(payload["recurrence"])
111
+ assert schedules._apply_cron(payload, _args())["recurrence"] == before
@@ -0,0 +1,309 @@
1
+ """Scheduler curated actions — faked client boundary (zero live HTTP).
2
+
3
+ Mirrors tests/test_transport.py / test_dispatch.py: a FakeSession records every
4
+ HTTP call and serves canned responses, so we assert the method, URL, query, and
5
+ body each curated schedule action emits.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import pytest
10
+
11
+ from tools.procesio import errors, main
12
+ from tools.procesio.client import ProcesioClient
13
+ from tools.procesio.tests.conftest import FakeResp, FakeSession
14
+
15
+
16
+ def _builder(profile, session):
17
+ return lambda prof: ProcesioClient(profile=profile, name="t", session=session)
18
+
19
+
20
+ APIKEY = {"type": "apikey", "key": "N", "value": "V"}
21
+
22
+
23
+ def _last(sess):
24
+ return sess.calls[-1]
25
+
26
+
27
+ # -- list / get -------------------------------------------------------------
28
+
29
+ def test_list_schedules_hits_endpoint():
30
+ sess = FakeSession(queue=[FakeResp(200, {"pageItems": []})])
31
+ out = main.dispatch("list-schedules", [], client_builder=_builder(APIKEY, sess))
32
+ assert out["result"] == {"pageItems": []}
33
+ c = _last(sess)
34
+ assert c["method"] == "GET"
35
+ assert c["url"].endswith("/api/Schedules")
36
+
37
+
38
+ def test_list_schedules_maps_paging():
39
+ sess = FakeSession(queue=[FakeResp(200, [])])
40
+ main.dispatch("list-schedules",
41
+ ["--page", "2", "--page-size", "25", "--search", "nightly"],
42
+ client_builder=_builder(APIKEY, sess))
43
+ assert _last(sess)["params"] == {"pageNumber": 2, "pageItemCount": 25,
44
+ "searchName": "nightly"}
45
+
46
+
47
+ def test_get_schedule_uses_id_in_path():
48
+ sess = FakeSession(queue=[FakeResp(200, {"id": "S1"})])
49
+ out = main.dispatch("get-schedule", ["--id", "S1"],
50
+ client_builder=_builder(APIKEY, sess))
51
+ assert out["result"] == {"id": "S1"}
52
+ c = _last(sess)
53
+ assert c["method"] == "GET"
54
+ assert c["url"].endswith("/api/Schedules/S1")
55
+
56
+
57
+ def test_get_schedule_preserves_process_inputs_by_default():
58
+ payload = {"id": "S1", "processInputs": [{"id": "V1", "value": "clear"}]}
59
+ sess = FakeSession(queue=[FakeResp(200, payload)])
60
+
61
+ out = main.dispatch("get-schedule", ["--id", "S1"],
62
+ client_builder=_builder(APIKEY, sess))
63
+
64
+ assert out["result"]["processInputs"][0]["value"] == "clear"
65
+
66
+
67
+ def test_get_schedule_can_redact_process_inputs_without_losing_structure():
68
+ payload = {
69
+ "id": "S1",
70
+ "processInputs": [
71
+ {"id": "V1", "value": "clear", "type": 0},
72
+ {"id": "V2", "value": None, "type": 0},
73
+ ],
74
+ "nested": {"ProcessInputs": [{"Id": "V3", "Value": "also-clear"}]},
75
+ }
76
+ sess = FakeSession(queue=[FakeResp(200, payload)])
77
+
78
+ out = main.dispatch(
79
+ "get-schedule",
80
+ ["--id", "S1", "--redact-process-inputs"],
81
+ client_builder=_builder(APIKEY, sess),
82
+ )["result"]
83
+
84
+ assert out["id"] == "S1"
85
+ assert out["processInputs"] == [
86
+ {"id": "V1", "value": "[REDACTED]", "type": 0},
87
+ {"id": "V2", "value": None, "type": 0},
88
+ ]
89
+ assert out["nested"]["ProcessInputs"][0] == {
90
+ "Id": "V3",
91
+ "Value": "[REDACTED]",
92
+ }
93
+ assert payload["processInputs"][0]["value"] == "clear"
94
+
95
+
96
+ @pytest.mark.parametrize("value", [False, 0, "", {"nested": "synthetic-value"}, ["synthetic-value"]])
97
+ def test_redaction_masks_entire_non_null_value_without_mutating_source(value):
98
+ payload = {"ProcessInputs": [{"Id": "V1", "Value": value}], "name": "example"}
99
+ sess = FakeSession(queue=[FakeResp(200, payload)])
100
+ result = main.dispatch(
101
+ "get-schedule", ["--id", "S1", "--redact-process-inputs"],
102
+ client_builder=_builder(APIKEY, sess),
103
+ )["result"]
104
+ assert result == {"ProcessInputs": [{"Id": "V1", "Value": "[REDACTED]"}], "name": "example"}
105
+ assert payload["ProcessInputs"][0]["Value"] == value
106
+
107
+
108
+ def test_projection_does_not_claim_arbitrary_field_sanitization():
109
+ payload = {"processInputs": ["synthetic-value", None, {"id": "V1"}],
110
+ "unrelated": "visible-metadata"}
111
+ sess = FakeSession(queue=[FakeResp(200, payload)])
112
+ result = main.dispatch(
113
+ "get-schedule", ["--id", "S1", "--redact-process-inputs"],
114
+ client_builder=_builder(APIKEY, sess),
115
+ )["result"]
116
+ assert result == {"processInputs": ["[REDACTED]", None, {"id": "V1"}],
117
+ "unrelated": "visible-metadata"}
118
+
119
+
120
+ def test_get_schedule_requires_id():
121
+ with pytest.raises(errors.UsageError):
122
+ main.dispatch("get-schedule", [], client_builder=_builder(APIKEY, FakeSession()))
123
+
124
+
125
+ # -- create / update --------------------------------------------------------
126
+
127
+ def test_create_schedule_posts_payload():
128
+ sess = FakeSession(queue=[FakeResp(200, {"id": "NEW"})])
129
+ body = '{"name":"nightly","flowId":"P1","isActive":false}'
130
+ out = main.dispatch("create-schedule", ["--payload", body],
131
+ client_builder=_builder(APIKEY, sess))
132
+ assert out["result"] == {"id": "NEW"}
133
+ c = _last(sess)
134
+ assert c["method"] == "POST"
135
+ assert c["url"].endswith("/api/Schedules")
136
+ assert c["json"] == {"name": "nightly", "flowId": "P1", "isActive": False}
137
+
138
+
139
+ def test_update_schedule_puts_payload():
140
+ sess = FakeSession(queue=[FakeResp(200, {"ok": True})])
141
+ body = '{"id":"S1","name":"nightly-v2"}'
142
+ main.dispatch("update-schedule", ["--payload", body],
143
+ client_builder=_builder(APIKEY, sess))
144
+ c = _last(sess)
145
+ assert c["method"] == "PUT"
146
+ assert c["url"].endswith("/api/Schedules")
147
+ assert c["json"] == {"id": "S1", "name": "nightly-v2"}
148
+
149
+
150
+ def test_create_schedule_cron_sets_recurrence_block():
151
+ sess = FakeSession(queue=[FakeResp(200, {"id": "NEW"})])
152
+ body = '{"name":"nightly","targetProcess":"P1"}'
153
+ main.dispatch("create-schedule",
154
+ ["--payload", body, "--cron", "0 6 * * *", "--timezone", "Europe/Bucharest"],
155
+ client_builder=_builder(APIKEY, sess))
156
+ rec = _last(sess)["json"]["recurrence"]
157
+ assert rec["recurrence"] == 8 # RecurrenceTypes.CRON
158
+ assert rec["cronExpression"] == "0 6 * * *"
159
+ assert rec["timeZone"] == "Europe/Bucharest"
160
+
161
+
162
+ def test_create_schedule_cron_drops_the_calendar_recurrence_fields():
163
+ """This test asserted the OPPOSITE until the designer's own PUT was captured.
164
+
165
+ Carrying a calendar field such as `isWeekendExcluded` into a cron recurrence makes the
166
+ API refuse the whole body with a generic 400 that names no field. The contract is a
167
+ REPLACEMENT, not an overlay — see tests/test_schedule_cron_shape.py.
168
+ """
169
+ sess = FakeSession(queue=[FakeResp(200, {})])
170
+ body = '{"name":"n","recurrence":{"isWeekendExcluded":true}}'
171
+ main.dispatch("create-schedule", ["--payload", body, "--cron", "*/5 * * * *"],
172
+ client_builder=_builder(APIKEY, sess))
173
+ rec = _last(sess)["json"]["recurrence"]
174
+ assert "isWeekendExcluded" not in rec
175
+ assert rec["recurrence"] == 8
176
+
177
+
178
+ def test_create_schedule_without_cron_posts_verbatim():
179
+ sess = FakeSession(queue=[FakeResp(200, {})])
180
+ main.dispatch("create-schedule", ["--payload", '{"name":"n"}'],
181
+ client_builder=_builder(APIKEY, sess))
182
+ assert _last(sess)["json"] == {"name": "n"} # no recurrence injected
183
+
184
+
185
+ def test_validate_crontab_posts_body():
186
+ sess = FakeSession(queue=[FakeResp(200, {"occurrences": []})])
187
+ main.dispatch("validate-crontab",
188
+ ["--cron", "0 9 * * 1-5", "--timezone", "UTC", "--count", "3"],
189
+ client_builder=_builder(APIKEY, sess))
190
+ c = _last(sess)
191
+ assert c["method"] == "POST"
192
+ assert c["url"].endswith("/api/Schedules/validate-crontab")
193
+ assert c["json"] == {"cronExpression": "0 9 * * 1-5", "timeZone": "UTC", "count": 3}
194
+
195
+
196
+ def test_create_schedule_requires_payload():
197
+ with pytest.raises(errors.UsageError):
198
+ main.dispatch("create-schedule", [],
199
+ client_builder=_builder(APIKEY, FakeSession()))
200
+
201
+
202
+ def test_create_schedule_rejects_bad_json():
203
+ with pytest.raises(errors.UsageError):
204
+ main.dispatch("create-schedule", ["--payload", "{bad"],
205
+ client_builder=_builder(APIKEY, FakeSession()))
206
+
207
+
208
+ # -- delete -----------------------------------------------------------------
209
+
210
+ def test_delete_schedule_uses_id_in_path():
211
+ sess = FakeSession(queue=[FakeResp(200, {})])
212
+ main.dispatch("delete-schedule", ["--id", "S9"],
213
+ client_builder=_builder(APIKEY, sess))
214
+ c = _last(sess)
215
+ assert c["method"] == "DELETE"
216
+ assert c["url"].endswith("/api/Schedules/S9")
217
+
218
+
219
+ # -- enable / disable -------------------------------------------------------
220
+
221
+ def test_set_status_maps_active_to_enable_query():
222
+ sess = FakeSession(queue=[FakeResp(200, {})])
223
+ main.dispatch("set-schedule-status", ["--id", "S1", "--active", "false"],
224
+ client_builder=_builder(APIKEY, sess))
225
+ c = _last(sess)
226
+ assert c["method"] == "PATCH"
227
+ assert c["url"].endswith("/api/Schedules/S1/status")
228
+ assert c["params"] == {"enable": "false"} # API param is `enable`
229
+ assert c["json"] is None
230
+
231
+
232
+ def test_set_status_active_true():
233
+ sess = FakeSession(queue=[FakeResp(200, {})])
234
+ main.dispatch("set-schedule-status", ["--id", "S1", "--active", "true"],
235
+ client_builder=_builder(APIKEY, sess))
236
+ assert _last(sess)["params"] == {"enable": "true"}
237
+
238
+
239
+ def test_set_status_rejects_non_bool_active():
240
+ with pytest.raises(errors.UsageError):
241
+ main.dispatch("set-schedule-status", ["--id", "S1", "--active", "yes"],
242
+ client_builder=_builder(APIKEY, FakeSession()))
243
+
244
+
245
+ # -- notifications ----------------------------------------------------------
246
+
247
+ def test_get_notifications_uses_id_in_path():
248
+ sess = FakeSession(queue=[FakeResp(200, {"emails": []})])
249
+ main.dispatch("get-schedule-notifications", ["--id", "S1"],
250
+ client_builder=_builder(APIKEY, sess))
251
+ c = _last(sess)
252
+ assert c["method"] == "GET"
253
+ assert c["url"].endswith("/api/Schedules/notifications/S1")
254
+
255
+
256
+ def test_set_notifications_posts_payload():
257
+ sess = FakeSession(queue=[FakeResp(200, {})])
258
+ body = '{"scheduleId":"S1","emails":["a@example.com"]}'
259
+ main.dispatch("set-schedule-notifications", ["--payload", body],
260
+ client_builder=_builder(APIKEY, sess))
261
+ c = _last(sess)
262
+ assert c["method"] == "POST"
263
+ assert c["url"].endswith("/api/Schedules/notifications")
264
+ assert c["json"] == {"scheduleId": "S1", "emails": ["a@example.com"]}
265
+
266
+
267
+ # -- project schedules ------------------------------------------------------
268
+
269
+ def test_list_project_schedules_uses_id_in_path():
270
+ sess = FakeSession(queue=[FakeResp(200, [])])
271
+ main.dispatch("list-project-schedules", ["--id", "P1"],
272
+ client_builder=_builder(APIKEY, sess))
273
+ c = _last(sess)
274
+ assert c["method"] == "GET"
275
+ assert c["url"].endswith("/api/Projects/P1/restricted/schedules")
276
+
277
+
278
+ def test_list_project_schedules_requires_id():
279
+ with pytest.raises(errors.UsageError):
280
+ main.dispatch("list-project-schedules", [],
281
+ client_builder=_builder(APIKEY, FakeSession()))
282
+
283
+
284
+ # -- time zone on calendar recurrences (Scheduler v3: rules run on the zone's local clock) --
285
+
286
+ def test_timezone_is_set_on_a_daily_recurrence():
287
+ sess = FakeSession(queue=[FakeResp(200, {"id": "NEW"})])
288
+ body = '{"name":"n","recurrence":{"recurrence":4,"every":1}}'
289
+ main.dispatch("create-schedule", ["--payload", body, "--timezone", "Europe/Bucharest"],
290
+ client_builder=_builder(APIKEY, sess))
291
+ rec = _last(sess)["json"]["recurrence"]
292
+ assert rec == {"recurrence": 4, "every": 1, "timeZone": "Europe/Bucharest"}
293
+
294
+
295
+ def test_timezone_is_refused_on_a_recurrence_that_ignores_it():
296
+ sess = FakeSession(queue=[FakeResp(200, {})])
297
+ body = '{"name":"n","recurrence":{"recurrence":2,"every":15}}'
298
+ with pytest.raises(errors.UsageError, match="no effect"):
299
+ main.dispatch("update-schedule", ["--payload", body, "--timezone", "UTC"],
300
+ client_builder=_builder(APIKEY, sess))
301
+ assert sess.calls == []
302
+
303
+
304
+ def test_a_payload_timezone_is_left_alone_without_the_flag():
305
+ sess = FakeSession(queue=[FakeResp(200, {})])
306
+ body = '{"name":"n","recurrence":{"recurrence":5,"timeZone":"Europe/Berlin"}}'
307
+ main.dispatch("create-schedule", ["--payload", body],
308
+ client_builder=_builder(APIKEY, sess))
309
+ assert _last(sess)["json"]["recurrence"]["timeZone"] == "Europe/Berlin"
@@ -0,0 +1,234 @@
1
+ """Execute Command <-> Execute Query family conversion + Output rebinding (flowmodel/sqlparam).
2
+
3
+ Why this exists: a stored procedure that ends in SELECT returns a RESULT SET, and only the
4
+ `Execute Query` family carries a result set back into a flow variable. `Execute Command` returns
5
+ rows-affected (its Output property is typed `number`), so a Command node pointed at a SELECT-ing
6
+ procedure silently discards everything the procedure returns and reports success. Converting the
7
+ family is the only fix; the conversion is a role-based property-id remap, exactly like the legacy
8
+ template migration, plus the Output setting's designer type.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import copy
13
+
14
+ import pytest
15
+
16
+ from tools.procesio.flowmodel import sqlparam as sp
17
+
18
+
19
+ def _command_node() -> dict:
20
+ """A parameterized Execute Command node whose SQL is an EXEC of a SELECT-ing procedure."""
21
+ sql = "EXEC meet.sp_BookMeeting @MeetingTypeID=@p0, @ClientName=@p1;"
22
+ bind_runtime = [
23
+ {"id": 0, "source": {"value": "<%0%>", "variable": [{"id": 0, "variableId": "var-a", "attribute": None}]},
24
+ "destination": {"value": "p0", "variable": []}},
25
+ {"id": 1, "source": {"value": "<%1%>", "variable": [{"id": 1, "variableId": "var-b", "attribute": None}]},
26
+ "destination": {"value": "p1", "variable": []}},
27
+ ]
28
+ return {
29
+ "id": "node-1",
30
+ "templateId": sp.EC_TEMPLATE_ID,
31
+ "actionName": "meet.sp_BookMeeting",
32
+ "actionTemplateName": "Execute Command",
33
+ "parameters": [
34
+ {"tabPropertyId": sp.EC_PID_CRED, "variable": [], "value": "cred-1"},
35
+ {"tabPropertyId": sp.EC_PID_COMMAND, "variable": [], "value": sql},
36
+ {"tabPropertyId": sp.EC_PID_BIND, "variable": [], "value": bind_runtime},
37
+ {"tabPropertyId": sp.EC_PID_TIMEOUT, "variable": [], "value": "60"},
38
+ {"tabPropertyId": sp.EC_PID_OUTPUT,
39
+ "variable": [{"id": 7, "variableId": "scalar-result", "attribute": None}], "value": "<%7%>"},
40
+ ],
41
+ "customData": {
42
+ "name": "meet.sp_BookMeeting",
43
+ "description": "Execute a custom SQL Command on the target database.",
44
+ "icon": "icon-mssql",
45
+ "configuration": [{
46
+ "id": "cfg-1", "label": "Execute Command", "orderId": 0,
47
+ "settings": [
48
+ {"id": sp.EC_PID_CRED, "label": "Select Database Server", "type": "credentials",
49
+ "value": "cred-1"},
50
+ {"id": sp.EC_PID_SIDEPANEL, "label": "Execute Command", "type": "side-pannel", "value": [
51
+ {"id": sp.EC_PID_COMMAND, "label": "Command", "type": "code-editor",
52
+ "language": "sql", "value": sql},
53
+ {"id": sp.EC_PID_BIND, "label": "Parameters config tab", "type": "map-parameters",
54
+ "value": [{"id": 0, "destination": "p0", "source": "var-a"},
55
+ {"id": 1, "destination": "p1", "source": "var-b"}]},
56
+ {"id": sp.EC_PID_TIMEOUT, "label": "Time Out", "type": "number", "value": "60"},
57
+ {"id": sp.EC_PID_OUTPUT, "label": "Output", "type": "number",
58
+ "value": "scalar-result"},
59
+ ]},
60
+ ],
61
+ }],
62
+ },
63
+ }
64
+
65
+
66
+ def _pid_values(node: dict) -> dict:
67
+ return {p["tabPropertyId"]: p.get("value") for p in node["parameters"]}
68
+
69
+
70
+ def _settings(node: dict) -> dict:
71
+ """{property id: setting} across the configuration, flattened through the side-pannel."""
72
+ out = {}
73
+ for cfg in node["customData"]["configuration"]:
74
+ for s in cfg["settings"]:
75
+ out[s["id"]] = s
76
+ if isinstance(s.get("value"), list):
77
+ for sub in s["value"]:
78
+ if isinstance(sub, dict) and "id" in sub:
79
+ out[sub["id"]] = sub
80
+ return out
81
+
82
+
83
+ # --------------------------------------------------------------------------- convert_family
84
+
85
+ def test_command_to_query_remaps_every_property_id_in_both_layers():
86
+ node = _command_node()
87
+ changed, msg = sp.convert_family(node, sp.EQ_TEMPLATE)
88
+
89
+ assert changed is True
90
+ assert "Execute Command -> Execute Query" in msg
91
+ assert node["templateId"] == sp.EQ_TEMPLATE_ID
92
+ assert node["actionTemplateName"] == sp.EQ_TEMPLATE
93
+
94
+ runtime = _pid_values(node)
95
+ assert sp.PID_CRED in runtime and sp.EC_PID_CRED not in runtime
96
+ assert sp.PID_QUERY in runtime and sp.EC_PID_COMMAND not in runtime
97
+ assert sp.PID_BIND in runtime and sp.EC_PID_BIND not in runtime
98
+ assert sp.PID_TIMEOUT in runtime and sp.EC_PID_TIMEOUT not in runtime
99
+ assert sp.PID_OUTPUT in runtime and sp.EC_PID_OUTPUT not in runtime
100
+
101
+ settings = _settings(node)
102
+ assert sp.PID_QUERY in settings and sp.EC_PID_COMMAND not in settings
103
+ assert sp.PID_BIND in settings and sp.EC_PID_BIND not in settings
104
+
105
+
106
+ def test_conversion_preserves_sql_credential_timeout_and_binding():
107
+ node = _command_node()
108
+ sql_before = _pid_values(node)[sp.EC_PID_COMMAND]
109
+ bind_before = copy.deepcopy(_pid_values(node)[sp.EC_PID_BIND])
110
+
111
+ sp.convert_family(node, sp.EQ_TEMPLATE)
112
+
113
+ runtime = _pid_values(node)
114
+ assert runtime[sp.PID_QUERY] == sql_before
115
+ assert runtime[sp.PID_CRED] == "cred-1"
116
+ assert runtime[sp.PID_TIMEOUT] == "60"
117
+ assert runtime[sp.PID_BIND] == bind_before, "the @param binding must survive the family change"
118
+
119
+
120
+ def test_conversion_relabels_the_designer_so_the_next_reader_is_not_misled():
121
+ node = _command_node()
122
+ sp.convert_family(node, sp.EQ_TEMPLATE)
123
+
124
+ settings = _settings(node)
125
+ assert settings[sp.PID_QUERY]["label"] == "Query"
126
+ assert settings[sp.PID_SIDEPANEL]["label"] == "Execute Query"
127
+ assert node["customData"]["configuration"][0]["label"] == "Execute Query"
128
+ assert "Query" in node["customData"]["description"]
129
+ assert "Command" not in node["customData"]["description"]
130
+
131
+
132
+ def test_output_setting_is_retyped_because_a_query_returns_a_result_set_not_a_count():
133
+ node = _command_node()
134
+ assert _settings(node)[sp.EC_PID_OUTPUT]["type"] == "number"
135
+
136
+ sp.convert_family(node, sp.EQ_TEMPLATE)
137
+
138
+ assert _settings(node)[sp.PID_OUTPUT]["type"] == "any"
139
+
140
+
141
+ def test_query_to_command_is_the_exact_inverse():
142
+ node = _command_node()
143
+ original = copy.deepcopy(node)
144
+
145
+ sp.convert_family(node, sp.EQ_TEMPLATE)
146
+ sp.convert_family(node, sp.EC_TEMPLATE)
147
+
148
+ assert node["templateId"] == original["templateId"]
149
+ assert _pid_values(node) == _pid_values(original)
150
+ assert _settings(node)[sp.EC_PID_OUTPUT]["type"] == "number"
151
+
152
+
153
+ def test_converting_to_the_family_it_is_already_on_is_a_no_op():
154
+ node = _command_node()
155
+ before = copy.deepcopy(node)
156
+
157
+ changed, msg = sp.convert_family(node, sp.EC_TEMPLATE)
158
+
159
+ assert changed is False
160
+ assert "already" in msg
161
+ assert node == before
162
+
163
+
164
+ def test_a_node_on_a_deprecated_template_is_refused_rather_than_half_converted():
165
+ node = _command_node()
166
+ node["templateId"] = "c2760ff2-cd9e-49b4-b751-c05c88e06dac" # Execute Command V1
167
+ before = copy.deepcopy(node)
168
+
169
+ changed, msg = sp.convert_family(node, sp.EQ_TEMPLATE)
170
+
171
+ assert changed is False
172
+ assert "deprecated" in msg
173
+ assert node == before, "a refused conversion must not leave the node partly remapped"
174
+
175
+
176
+ def test_a_non_sql_node_is_refused():
177
+ node = {"actionTemplateName": "Node", "templateId": "whatever", "parameters": [], "customData": {}}
178
+ changed, msg = sp.convert_family(node, sp.EQ_TEMPLATE)
179
+ assert changed is False
180
+ assert "SQL" in msg
181
+
182
+
183
+ def test_an_unknown_target_family_raises_rather_than_silently_doing_nothing():
184
+ with pytest.raises(ValueError):
185
+ sp.convert_family(_command_node(), "Execute Something")
186
+
187
+
188
+ # --------------------------------------------------------------------------- rebind_output
189
+
190
+ def test_rebind_output_moves_both_layers_to_the_new_variable():
191
+ node = _command_node()
192
+ sp.convert_family(node, sp.EQ_TEMPLATE)
193
+
194
+ changed, _ = sp.rebind_output(node, "resultset-var")
195
+
196
+ assert changed is True
197
+ out = next(p for p in node["parameters"] if p["tabPropertyId"] == sp.PID_OUTPUT)
198
+ assert out["variable"][0]["variableId"] == "resultset-var"
199
+ assert _settings(node)[sp.PID_OUTPUT]["value"] == "resultset-var"
200
+
201
+
202
+ def test_rebind_output_keeps_the_positional_slot_so_it_cannot_collide_with_a_param_bind():
203
+ node = _command_node()
204
+ sp.convert_family(node, sp.EQ_TEMPLATE)
205
+ slot_before = next(p for p in node["parameters"] if p["tabPropertyId"] == sp.PID_OUTPUT)["value"]
206
+
207
+ sp.rebind_output(node, "resultset-var")
208
+
209
+ out = next(p for p in node["parameters"] if p["tabPropertyId"] == sp.PID_OUTPUT)
210
+ assert out["value"] == slot_before == "<%7%>"
211
+ bound = {b["source"]["value"] for b in _pid_values(node)[sp.PID_BIND]}
212
+ assert out["value"] not in bound
213
+
214
+
215
+ def test_rebind_output_to_the_same_variable_reports_no_change():
216
+ node = _command_node()
217
+ changed, msg = sp.rebind_output(node, "scalar-result")
218
+ assert changed is False
219
+ assert "already" in msg
220
+
221
+
222
+ def test_rebind_output_seeds_the_binding_when_the_node_has_none():
223
+ node = _command_node()
224
+ out = next(p for p in node["parameters"] if p["tabPropertyId"] == sp.EC_PID_OUTPUT)
225
+ out["variable"] = []
226
+ out["value"] = None
227
+
228
+ changed, _ = sp.rebind_output(node, "fresh-var")
229
+
230
+ assert changed is True
231
+ out = next(p for p in node["parameters"] if p["tabPropertyId"] == sp.EC_PID_OUTPUT)
232
+ assert out["variable"][0]["variableId"] == "fresh-var"
233
+ # the slot must sit past every @param bind index, or the engine reads the wrong value
234
+ assert out["value"] == "<%2%>"