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,373 @@
1
+ """Process builder: For-Each containment + Call/Trigger Subprocess mapping (Tier-2)."""
2
+ from __future__ import annotations
3
+
4
+ import itertools
5
+
6
+ import pytest
7
+
8
+ from tools.procesio.dto.process import builder as pb
9
+ from tools.procesio.errors import UsageError
10
+
11
+
12
+ def _ctx():
13
+ counter = itertools.count(1)
14
+ return {"new_id": lambda: f"00000000-0000-0000-0000-{next(counter):012d}"}
15
+
16
+
17
+ def _by_cid(dto):
18
+ return {a["ActionName"]: a for a in dto["Actions"]}
19
+
20
+
21
+ # -- For-Each containment ----------------------------------------------------
22
+
23
+ def test_foreach_body_is_parented():
24
+ cfg = {"title": "loop", "actions": [
25
+ {"id": "loop", "action": "For Each", "name": "loop"},
26
+ {"id": "body", "action": "Map Data", "name": "body", "parent": "loop"},
27
+ ]}
28
+ dto = pb.build(cfg, _ctx())
29
+ nodes = _by_cid(dto)
30
+ loop, body = nodes["loop"], nodes["body"]
31
+ assert loop["CustomData"]["type"] == "area"
32
+ # the layout engine sizes the For-Each frame to bound its child (not the 48x48 default)
33
+ assert loop["CustomData"]["areaSize"]["width"] >= 48
34
+ assert loop["CustomData"]["areaSize"]["height"] >= 48
35
+ # the body action points at the For-Each node id
36
+ assert body["ParentId"] == loop["Id"]
37
+ # a normal (non-area) node keeps the small node frame
38
+ assert body["CustomData"]["areaSize"]["width"] == 48
39
+ # the built process renders correctly: body inside the loop frame, stored RELATIVE
40
+ from tools.procesio.layout import adapter
41
+ assert adapter.verify_render(dto)["ok"]
42
+ bp = body["CustomData"]["position"]
43
+ asz = loop["CustomData"]["areaSize"]
44
+ assert 0 <= bp["x"] <= asz["width"] and 0 <= bp["y"] <= asz["height"]
45
+
46
+
47
+ def test_non_parented_action_has_null_parent():
48
+ cfg = {"title": "t", "actions": [{"id": "g", "action": "Generate GUID"}]}
49
+ dto = pb.build(cfg, _ctx())
50
+ assert all(a["ParentId"] is None for a in dto["Actions"])
51
+
52
+
53
+ def test_unknown_parent_raises():
54
+ cfg = {"title": "t", "actions": [
55
+ {"id": "a", "action": "Map Data", "parent": "nope"}]}
56
+ with pytest.raises(UsageError):
57
+ pb.build(cfg, _ctx())
58
+
59
+
60
+ def test_nested_foreach_rejected():
61
+ cfg = {"title": "t", "actions": [
62
+ {"id": "outer", "action": "For Each"},
63
+ {"id": "inner", "action": "For Each", "parent": "outer"}]}
64
+ with pytest.raises(UsageError, match="cannot be nested"):
65
+ pb.build(cfg, _ctx())
66
+
67
+
68
+ # -- template default-valued OUTPUT slots (For Each hang) --
69
+ # A For Each built from the compact config must carry the two runtime-written output
70
+ # slots the designer materialises — `Zero based list index` (61724e="-1") and
71
+ # `Action start time` (808b0d=the 2010 sentinel) — or the loop iterates its body ZERO
72
+ # times and times out. The builder is binding-driven and used to drop them; it now
73
+ # materialises any `direction:2 / type:ignore` template setting carrying a scalar
74
+ # default that no binding supplied.
75
+ FE_IDX = "99e8766d-d6be-4948-8f57-1f141f61724e" # Zero based list index -> "-1"
76
+ FE_START = "9d2d3483-f04b-48ac-9dea-2ef7ae808b0d" # Action start time -> 2010-... sentinel
77
+
78
+
79
+ def _params_by_id(action):
80
+ return {p["TabPropertyId"]: p for p in action["Parameters"]}
81
+
82
+
83
+ def test_foreach_materialises_template_default_outputs():
84
+ cfg = {"title": "loop", "variables": [
85
+ {"name": "items", "type": "string", "direction": "process", "isList": True},
86
+ {"name": "cur", "type": "string", "direction": "process"}],
87
+ "actions": [
88
+ {"id": "loop", "action": "For Each", "name": "loop",
89
+ "params": {"In List": {"var": "items"}, "For Each Item": {"var": "cur"},
90
+ "Action timeout": 120}},
91
+ {"id": "body", "action": "Map Data", "name": "body", "parent": "loop"}]}
92
+ loop = _by_cid(pb.build(cfg, _ctx()))["loop"]
93
+ P = _params_by_id(loop)
94
+ # the three bound params AND the two template-default outputs = 5 total
95
+ assert len(loop["Parameters"]) == 5
96
+ assert FE_IDX in P and P[FE_IDX]["Value"] == "-1" and P[FE_IDX]["Variable"] == []
97
+ assert FE_START in P and str(P[FE_START]["Value"]).startswith("2010-01-01T00:00:00")
98
+ assert P[FE_START]["Variable"] == []
99
+
100
+
101
+ def test_foreach_default_outputs_are_append_only():
102
+ """The materialised outputs are APPENDED after the bound params; the bound
103
+ params keep their identity and order (a transform, not a rewrite)."""
104
+ cfg = {"title": "loop", "variables": [
105
+ {"name": "items", "type": "string", "direction": "process", "isList": True},
106
+ {"name": "cur", "type": "string", "direction": "process"}],
107
+ "actions": [{"id": "loop", "action": "For Each", "name": "loop",
108
+ "params": {"In List": {"var": "items"}, "For Each Item": {"var": "cur"},
109
+ "Action timeout": 120}}]}
110
+ loop = _by_cid(pb.build(cfg, _ctx()))["loop"]
111
+ ids = [p["TabPropertyId"] for p in loop["Parameters"]]
112
+ # the two materialised slots come LAST, after the three bound ones
113
+ assert ids[-2:] == [FE_IDX, FE_START] or set(ids[-2:]) == {FE_IDX, FE_START}
114
+ assert ids.index(FE_IDX) >= 3 and ids.index(FE_START) >= 3
115
+
116
+
117
+ def test_paramless_foreach_still_gets_the_two_outputs():
118
+ """Even a For Each the config binds nothing on (empty params -> the early
119
+ return in _action_parameters) still receives the two template defaults."""
120
+ cfg = {"title": "t", "actions": [{"id": "loop", "action": "For Each"}]}
121
+ loop = next(a for a in pb.build(cfg, _ctx())["Actions"]
122
+ if a["CustomData"]["type"] == "area")
123
+ P = _params_by_id(loop)
124
+ assert FE_IDX in P and FE_START in P and len(loop["Parameters"]) == 2
125
+
126
+
127
+ def test_non_foreach_action_gains_no_template_defaults():
128
+ """An action whose template has no defaulted OUTPUT slot gains no OUTPUT default.
129
+
130
+ The INPUT half of this guard was SUPERSEDED upstream. `_ensure_input_defaults`
131
+ now materialises a template's input defaults deliberately: an unbound Node
132
+ `Timeout` was dropped, the engine ran it as 00:00:00 and the action died with
133
+ "value ('00:00:00') must be greater than '00:00:00'" (verified live). So a bare
134
+ Node legitimately carries its default "60" now, and the three tests around
135
+ `test_node_unbound_timeout_gets_template_default` pin that behaviour. What must
136
+ still never appear is an OUTPUT-side slot: that is what the For Each fix touched,
137
+ and its blast radius is what this test exists to hold.
138
+ """
139
+ cfg = {"title": "t", "actions": [{"id": "n", "action": "Node", "name": "n"}]}
140
+ n = _by_cid(pb.build(cfg, _ctx()))["n"]
141
+ # the input default 177a57 ("60") is intended; nothing else may be materialised
142
+ assert [p["TabPropertyId"] for p in n["Parameters"]] == [
143
+ "d3e52aab-b9d0-2d42-911e-b0e6de177a57"]
144
+
145
+
146
+ def test_call_subprocess_started_flow_not_doubled():
147
+ """Call Subprocess's a03fe2 started-flow slot (direction 2/ignore, default the
148
+ null guid) is already emitted by _build_subprocess; the materialiser must dedupe
149
+ it, not emit a second copy."""
150
+ cfg = _sub_cfg()
151
+ call = _by_cid(pb.build(cfg, _ctx()))["call"]
152
+ a03 = [p for p in call["Parameters"] if p["TabPropertyId"].endswith("a03fe2")]
153
+ assert len(a03) == 1 and a03[0]["Value"] == pb.NULL_GUID
154
+
155
+
156
+ # -- Call/Trigger Subprocess --------------------------------------------------
157
+
158
+ TARGET = "b8f1d9e7-906e-46fa-9947-8700d1602d22"
159
+ SUB_IN = "0f1e0ceb-6c83-4f5e-b2f3-8b013ae13865"
160
+ SUB_OUT = "39d984af-ba12-4e42-82be-327ef9d51648"
161
+
162
+
163
+ def _sub_cfg():
164
+ return {"title": "caller",
165
+ "variables": [{"name": "x", "type": "string"},
166
+ {"name": "y", "type": "string", "direction": "output"}],
167
+ "actions": [{"id": "call", "action": "Call Subprocess", "name": "call",
168
+ "subprocess": {"target": TARGET,
169
+ "inputs": {SUB_IN: {"var": "x"}},
170
+ "outputs": {"y": SUB_OUT}}}]}
171
+
172
+
173
+ def _settings_by_type(node):
174
+ out = {}
175
+
176
+ def walk(settings):
177
+ for s in settings or []:
178
+ out.setdefault(s.get("type"), []).append(s)
179
+ if isinstance(s.get("value"), list):
180
+ walk(s["value"])
181
+ for tab in node["CustomData"]["configuration"]:
182
+ walk(tab.get("settings", []))
183
+ return out
184
+
185
+
186
+ def test_subprocess_target_and_maps_build():
187
+ dto = pb.build(_sub_cfg(), _ctx())
188
+ call = _by_cid(dto)["call"]
189
+ params = {p["TabPropertyId"]: p for p in call["Parameters"]}
190
+ # flow-list param carries the target flow id
191
+ flow_vals = [p["Value"] for p in call["Parameters"] if p["Value"] == TARGET]
192
+ assert flow_vals == [TARGET]
193
+ # the designer config exposes the {subprocess, process} rows
194
+ by_type = _settings_by_type(call)
195
+ in_rows = by_type["process-inputs"][0]["value"]
196
+ assert in_rows and in_rows[0]["subprocess"] == SUB_IN # destination = sub input var
197
+ assert in_rows[0]["process"] # parent var id resolved
198
+ out_rows = by_type["process-outputs"][0]["value"]
199
+ assert out_rows and out_rows[0]["subprocess"] == SUB_OUT # source = sub output var
200
+ assert out_rows[0]["process"] # parent (y) var id
201
+
202
+
203
+ def test_subprocess_runtime_rows_match_doc_mapper_shape():
204
+ dto = pb.build(_sub_cfg(), _ctx())
205
+ call = _by_cid(dto)["call"]
206
+ in_param = next(p for p in call["Parameters"]
207
+ if isinstance(p["Value"], list) and p["Value"]
208
+ and p["Value"][0].get("destination", {}).get("variableId") == SUB_IN)
209
+ row = in_param["Value"][0]
210
+ assert "source" in row and "destination" in row
211
+ assert row["destination"]["variableId"] == SUB_IN
212
+ assert row["source"]["variable"][0]["variableId"] # bound to parent var x
213
+
214
+
215
+ def test_subprocess_unknown_output_var_raises():
216
+ cfg = _sub_cfg()
217
+ cfg["actions"][0]["subprocess"]["outputs"] = {"missing": SUB_OUT}
218
+ with pytest.raises(UsageError):
219
+ pb.build(cfg, _ctx())
220
+
221
+
222
+ def test_subprocess_build_passes_config_audit():
223
+ # build() runs _audit_config internally; a clean build means the designer would
224
+ # show the subprocess rows configured (not empty/invalid).
225
+ pb.build(_sub_cfg(), _ctx()) # must not raise
226
+
227
+
228
+ # -- edit-time layout: preserve existing positions + scoped relayout ----------
229
+
230
+ def _two_action_cfg():
231
+ return {"title": "t", "actions": [
232
+ {"id": "a", "action": "Generate GUID"},
233
+ {"id": "b", "action": "Map Data"}]}
234
+
235
+
236
+ _EXISTING = {"a": {"x": 999, "y": 111}, "b": {"x": 1500, "y": 222},
237
+ "start": {"x": 10, "y": 20}, "stop": {"x": 2000, "y": 300}}
238
+
239
+
240
+ def test_create_uses_engine_layout():
241
+ # a fresh build (no existing positions) lays out left-to-right from the margin
242
+ dto = pb.build(_two_action_cfg(), _ctx())
243
+ assert _by_cid(dto)["Start"]["CustomData"]["position"] == {"x": 80.0, "y": 80.0}
244
+
245
+
246
+ def test_edit_default_rearranges_the_whole_canvas(monkeypatch):
247
+ # an edit gets the same full arrangement as a create (classic engine + clustering),
248
+ # so a process edited many times never drifts into an unarranged canvas
249
+ monkeypatch.delenv("PROCESIO_KEEP_LAYOUT", raising=False)
250
+ ctx = {**_ctx(), "existing_positions": _EXISTING}
251
+ nodes = _by_cid(pb.build(_two_action_cfg(), ctx))
252
+ assert nodes["Start"]["CustomData"]["position"] == {"x": 80.0, "y": 80.0} # re-tidied
253
+ assert nodes["Generate GUID"]["CustomData"]["position"] != {"x": 999, "y": 111}
254
+
255
+
256
+ def test_edit_keep_layout_preserves_everyone_when_nothing_new():
257
+ ctx = {**_ctx(), "existing_positions": _EXISTING}
258
+ nodes = _by_cid(pb.build({**_two_action_cfg(), "relayout": "new"}, ctx))
259
+ assert nodes["Generate GUID"]["CustomData"]["position"] == {"x": 999, "y": 111}
260
+ assert nodes["Map Data"]["CustomData"]["position"] == {"x": 1500, "y": 222}
261
+ assert nodes["Start"]["CustomData"]["position"] == {"x": 10, "y": 20}
262
+
263
+
264
+ def test_edit_keep_layout_env_preserves_existing(monkeypatch):
265
+ monkeypatch.setenv("PROCESIO_KEEP_LAYOUT", "1")
266
+ ctx = {**_ctx(), "existing_positions": _EXISTING}
267
+ nodes = _by_cid(pb.build(_two_action_cfg(), ctx))
268
+ assert nodes["Start"]["CustomData"]["position"] == {"x": 10, "y": 20}
269
+
270
+
271
+ def test_edit_keep_layout_places_new_action_preserves_existing():
272
+ cfg = {"title": "t", "relayout": "new", "actions": [
273
+ {"id": "a", "action": "Generate GUID"},
274
+ {"id": "c", "action": "Add"}]} # 'c' is new (not in existing)
275
+ existing = {"a": {"x": 999, "y": 111}, "start": {"x": 10, "y": 20},
276
+ "stop": {"x": 2000, "y": 300}}
277
+ nodes = _by_cid(pb.build(cfg, {**_ctx(), "existing_positions": existing}))
278
+ assert nodes["Generate GUID"]["CustomData"]["position"] == {"x": 999, "y": 111} # stays
279
+ # the new action got an engine-computed position (not left at the provisional grid)
280
+ assert nodes["Add"]["CustomData"]["position"] != {"x": 999, "y": 111}
281
+
282
+
283
+ def test_edit_relayout_all_does_full_layout():
284
+ ctx = {**_ctx(), "existing_positions": _EXISTING}
285
+ cfg = {**_two_action_cfg(), "relayout": "all"}
286
+ nodes = _by_cid(pb.build(cfg, ctx))
287
+ assert nodes["Start"]["CustomData"]["position"] == {"x": 80.0, "y": 80.0} # re-tidied
288
+
289
+
290
+ def test_edit_relayout_subset_moves_only_that_action():
291
+ ctx = {**_ctx(), "existing_positions": _EXISTING}
292
+ cfg = {**_two_action_cfg(), "relayout": ["b"]}
293
+ nodes = _by_cid(pb.build(cfg, ctx))
294
+ assert nodes["Generate GUID"]["CustomData"]["position"] == {"x": 999, "y": 111} # stays
295
+ assert nodes["Start"]["CustomData"]["position"] == {"x": 10, "y": 20} # stays
296
+ assert nodes["Map Data"]["CustomData"]["position"] != {"x": 1500, "y": 222} # moved
297
+
298
+
299
+ # -- Shapes / canvasData preservation on edit (canvas-engine PRC-4391) -------
300
+
301
+ class _CanvasClient:
302
+ """Serves a live flow carrying canvasData (viewport + decorative shapes) and
303
+ captures the PUT DTO, so we can assert an edit preserves it."""
304
+ def __init__(self, canvas):
305
+ self._flow = {"flow": {"variables": [], "actions": [], "canvasData": canvas}}
306
+ self.put_dto = None
307
+
308
+ def get(self, path, query=None):
309
+ return self._flow
310
+
311
+ def put(self, path, body=None, query=None):
312
+ self.put_dto = body
313
+ return {}
314
+
315
+ def post(self, path, body=None, query=None):
316
+ return {"raw_text": ""}
317
+
318
+
319
+ def test_edit_preserves_canvas_shapes(monkeypatch):
320
+ monkeypatch.setattr(pb, "_save_gate", lambda *a, **k: None) # isolate preservation
321
+ shapes = [{"id": "s1", "kind": "rectangle", "title": "Zone A"}]
322
+ canvas = {"shapes": shapes, "viewport": {"x": 5, "y": 9, "zoom": 1.2}}
323
+ c = _CanvasClient(canvas)
324
+ pb._edit(c, "P1", {"title": "t", "actions": []}, {**_ctx(), "_force": True})
325
+ assert c.put_dto["CanvasData"] == canvas # shapes + viewport survive the edit
326
+
327
+
328
+ def test_edit_without_canvas_leaves_canvasdata_none(monkeypatch):
329
+ monkeypatch.setattr(pb, "_save_gate", lambda *a, **k: None)
330
+ c = _CanvasClient(None) # live flow has no canvasData
331
+ pb._edit(c, "P1", {"title": "t", "actions": []}, {**_ctx(), "_force": True})
332
+ assert c.put_dto["CanvasData"] is None # nothing to preserve, no crash
333
+
334
+
335
+ # -- input-side template defaults (B-048 cluster 2) --------------------------
336
+
337
+ def _node_cfg(params):
338
+ return {"title": "n",
339
+ "variables": [{"name": "out", "type": "json", "direction": "output"}],
340
+ "actions": [{"id": "n", "action": "Node", "name": "nd", "params": params}]}
341
+
342
+
343
+ def test_node_unbound_timeout_gets_template_default():
344
+ # An unbound Node Timeout was dropped and the engine ran it as 00:00:00, dying with
345
+ # "value ('00:00:00') must be greater than '00:00:00'". The builder now materialises
346
+ # the template default (60), matching what the designer pre-fills. Verified live.
347
+ dto = pb.build(_node_cfg({"Code": {"template": "return 42;", "vars": []},
348
+ "Single Result": {"var": "out"}}), _ctx())
349
+ node = _by_cid(dto)["nd"]
350
+ assert "60" in [p.get("Value") for p in node["Parameters"]]
351
+
352
+
353
+ def test_bound_input_default_is_not_overridden_or_duplicated():
354
+ dto = pb.build(_node_cfg({"Code": {"template": "return 1;", "vars": []},
355
+ "Timeout": 120, "Single Result": {"var": "out"}}), _ctx())
356
+ node = _by_cid(dto)["nd"]
357
+ vals = [p.get("Value") for p in node["Parameters"]]
358
+ assert 120 in vals and "60" not in vals # user value kept, default not re-added
359
+
360
+
361
+ def test_ensure_input_defaults_subclass_and_skips():
362
+ tpl = {"name": "X", "configuration": [{"settings": [
363
+ {"id": "a", "direction": 1, "type": "number", "value": "7"}, # materialise
364
+ {"id": "b", "direction": 1, "type": "code-editor", "value": "f(){}"}, # skip: code
365
+ {"id": "c", "direction": 1, "type": "text", "value": ""}, # skip: empty
366
+ {"id": "d", "direction": 3, "type": "number", "value": "9"}, # skip: output
367
+ {"id": "e", "direction": 1, "type": "select", "value": "1"}, # materialise
368
+ ]}]}
369
+ got = {p["TabPropertyId"]: p["Value"] for p in pb._ensure_input_defaults(tpl, [])}
370
+ assert got == {"a": "7", "e": "1"}
371
+ # an already-bound property is never re-materialised
372
+ got2 = pb._ensure_input_defaults(tpl, [{"TabPropertyId": "a", "Variable": [], "Value": "99"}])
373
+ assert [p for p in got2 if p["TabPropertyId"] == "a" and p["Value"] == "7"] == []
@@ -0,0 +1,183 @@
1
+ """Tier-3 parity hardening: credential binding + locked builder invariants.
2
+
3
+ The invariants (shape inherited from the action; decisional fan-out unlimited) are already
4
+ correct in the builder — these tests lock them so a future change can't silently break them.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import itertools
9
+
10
+ import pytest
11
+
12
+ from tools.procesio.dto.process import builder as pb
13
+ from tools.procesio.errors import UsageError
14
+
15
+
16
+ def _ctx():
17
+ counter = itertools.count(1)
18
+ return {"new_id": lambda: f"00000000-0000-0000-0000-{next(counter):012d}"}
19
+
20
+
21
+ def _by_name(dto):
22
+ return {a["ActionName"]: a for a in dto["Actions"]}
23
+
24
+
25
+ def _cfg_setting(node, label):
26
+ def walk(settings):
27
+ for s in settings or []:
28
+ if str(s.get("label", "")).lower() == label.lower():
29
+ return s
30
+ if isinstance(s.get("value"), list):
31
+ r = walk(s["value"])
32
+ if r:
33
+ return r
34
+ for tab in node["CustomData"]["configuration"]:
35
+ r = walk(tab.get("settings", []))
36
+ if r:
37
+ return r
38
+
39
+
40
+ def test_number_setting_designer_value_is_string():
41
+ """A DESIGNER number input binds a STRING; a numeric config value renders EMPTY
42
+ and the FE range-check then reads Number("")=0 -> "value between min and max"
43
+ (even though the RUNTIME Parameter, which stays numeric, executes fine). So the
44
+ builder must mirror number-type settings (e.g. a Node's Timeout) as strings."""
45
+ cfg = {"title": "t",
46
+ "variables": [{"name": "x", "type": "json", "direction": "input"},
47
+ {"name": "r", "type": "json", "direction": "output"}],
48
+ "actions": [{"id": "n", "action": "Node", "name": "n",
49
+ "params": {"Code": {"template": "return <%0%>;", "vars": ["x"]},
50
+ "Timeout": 60, "Single Result": {"var": "r"}}}]}
51
+ node = _by_name(pb.build(cfg, _ctx()))["n"]
52
+ s = _cfg_setting(node, "Timeout")
53
+ assert s["value"] == "60" and isinstance(s["value"], str) # designer: string
54
+ assert any(p["Value"] == 60 for p in node["Parameters"]) # runtime: numeric, unchanged
55
+
56
+
57
+ # -- credential binding -------------------------------------------------------
58
+
59
+ CRED_GID = "45a1dd18-9d06-47cf-8a7b-7732447264af"
60
+
61
+
62
+ def _cred_setting(node):
63
+ for tab in node["CustomData"]["configuration"]:
64
+ for s in tab.get("settings", []):
65
+ if s.get("type") == "credentials":
66
+ return s
67
+ return None
68
+
69
+
70
+ def test_credential_binding_sets_gid_and_keeps_template():
71
+ cfg = {"title": "q", "variables": [{"name": "q", "type": "string"}],
72
+ "actions": [{"id": "eq", "action": "Execute Query", "name": "eq",
73
+ "params": {"Select Database Server": {"credential": CRED_GID},
74
+ "Query": {"var": "q"}}}]}
75
+ dto = pb.build(cfg, _ctx())
76
+ eq = _by_name(dto)["eq"]
77
+ # runtime Parameter carries the instance gid
78
+ cred_params = [p for p in eq["Parameters"] if p["Value"] == CRED_GID]
79
+ assert len(cred_params) == 1 and cred_params[0]["Variable"] == []
80
+ # designer config: value = gid AND the credential TEMPLATE id is preserved
81
+ s = _cred_setting(eq)
82
+ assert s["value"] == CRED_GID
83
+ assert s.get("credentialsTemplateId") # the credential TYPE, from the catalog
84
+
85
+
86
+ def test_credential_binding_rejects_non_guid():
87
+ cfg = {"title": "q", "actions": [
88
+ {"id": "eq", "action": "Execute Query",
89
+ "params": {"Select Database Server": {"credential": "not-a-guid"}}}]}
90
+ with pytest.raises(UsageError, match="credential"):
91
+ pb.build(cfg, _ctx())
92
+
93
+
94
+ # -- invariant: node shape is action-dictated, never hardcoded ---------------
95
+
96
+ def test_node_shape_inherited_from_action():
97
+ """Every node's CustomData.type equals its catalog template's `shape` — i.e. the
98
+ shape is inherited from the action, never assigned per action by the builder."""
99
+ cfg = {"title": "shapes", "variables": [{"name": "n", "type": "integer"}],
100
+ "actions": [
101
+ {"id": "g", "action": "Generate GUID"},
102
+ {"id": "loop", "action": "For Each"},
103
+ {"id": "d", "action": "Decisional",
104
+ "branches": [{"to": "g", "when": [{"left": {"var": "n"}, "op": "EQUALS", "right": 1}]},
105
+ {"to": "loop", "default": True}]},
106
+ ]}
107
+ dto = pb.build(cfg, _ctx())
108
+ catalog = pb.catalog_index()
109
+ for a in dto["Actions"]:
110
+ tpl = catalog.get((a["ActionTemplateName"] or "").strip().lower())
111
+ assert tpl is not None, f"no catalog template for {a['ActionTemplateName']!r}"
112
+ assert a["CustomData"]["type"] == (tpl.get("shape") or "square"), \
113
+ f"{a['ActionTemplateName']} shape not inherited from catalog"
114
+ # and the catalog genuinely carries distinct shapes (so the test isn't vacuous)
115
+ shapes = {a["CustomData"]["type"] for a in dto["Actions"]}
116
+ assert {"diamond", "area"} <= shapes
117
+
118
+
119
+ def test_decisional_fanout_is_unlimited():
120
+ # 6 cases + a default — must all be emitted (no 2-5 cap)
121
+ targets = [{"id": f"t{i}", "action": "Generate GUID"} for i in range(6)]
122
+ branches = [{"to": f"t{i}", "when": [{"left": {"var": "n"}, "op": "EQUALS", "right": i}]}
123
+ for i in range(6)]
124
+ branches.append({"to": "t0", "default": True})
125
+ cfg = {"title": "fan", "variables": [{"name": "n", "type": "integer"}],
126
+ "actions": [{"id": "d", "action": "Decisional", "branches": branches}] + targets}
127
+ dto = pb.build(cfg, _ctx())
128
+ d = _by_name(dto)["Decisional"]
129
+ cases_param = next(p for p in d["Parameters"] if isinstance(p["Value"], list)
130
+ and p["Value"] and "actionid" in p["Value"][0])
131
+ assert len(cases_param["Value"]) == 6 # all six cases survive (no 2-5 cap)
132
+ # at least the 6 case ports + 1 default port leave the decisional
133
+ assert sum(1 for pt in d["Ports"] if pt["SourceId"] == d["Id"]) >= 7
134
+
135
+
136
+ def test_decisional_no_duplicate_linear_outgoing_port():
137
+ # regression: with no explicit `edges` the implicit linear chain (start->...->stop)
138
+ # must NOT add an outgoing edge from a Decisional - its outgoing routing is its
139
+ # `branches` only. An extra linear port double-ports the node and the BE rejects it
140
+ # ("multiple incoming" / "duplicate connection").
141
+ cfg = {"title": "d", "variables": [{"name": "n", "type": "integer"}],
142
+ "actions": [
143
+ {"id": "d", "action": "Decisional",
144
+ "branches": [{"to": "a", "when": [{"left": {"var": "n"}, "op": "EQUALS", "right": 1}]},
145
+ {"to": "b", "default": True}]},
146
+ {"id": "a", "action": "Generate GUID"},
147
+ {"id": "b", "action": "Generate GUID"}]}
148
+ dto = pb.build(cfg, _ctx()) # no `edges` -> chain would have added d->a
149
+ d = _by_name(dto)["Decisional"]
150
+ outgoing = [pt for pt in d["Ports"] if pt["SourceId"] == d["Id"]]
151
+ assert len(outgoing) == 2 # exactly the 2 branches, no linear duplicate
152
+
153
+
154
+ def test_subprocess_literal_input_hoisted_to_variable():
155
+ # A LITERAL subprocess input must be hoisted to a synthetic process variable (default =
156
+ # the literal) and the binding rewritten to {var: ...}, so the mapping's parent side is
157
+ # a real variable id (a raw literal there makes the designer reject a Trigger Subprocess
158
+ # as "Mapping of required subprocess variable (X) is missing", blocking the launch).
159
+ cfg = {"title": "sub", "variables": [{"name": "f", "model": "FileDataModel"}],
160
+ "actions": [{"id": "t", "action": "Trigger Subprocess", "subprocess": {
161
+ "target": "d7af1675-abe3-4193-a8e6-ef6aa501f78c",
162
+ "inputs": {"S1": {"value": "hello.pdf"}, "S2": {"var": "f"}, "S3": 42},
163
+ "outputs": {}}}]}
164
+ out = pb._hoist_subprocess_literals(cfg)
165
+ inputs = out["actions"][0]["subprocess"]["inputs"]
166
+ # both literals ({"value":...} and a bare scalar) became {var: <synthetic>}; the var stays
167
+ assert set(inputs["S1"].keys()) == {"var"} and set(inputs["S3"].keys()) == {"var"}
168
+ assert inputs["S2"] == {"var": "f"} # var binding untouched
169
+ syn = {v["name"]: v for v in out["variables"] if v["name"].startswith("_sublit")}
170
+ assert len(syn) == 2
171
+ assert syn[inputs["S1"]["var"]]["default"] == "hello.pdf"
172
+ assert syn[inputs["S1"]["var"]]["type"] == "string"
173
+ assert syn[inputs["S3"]["var"]]["default"] == 42
174
+ assert syn[inputs["S3"]["var"]]["type"] == "integer"
175
+ # the original config is not mutated
176
+ assert cfg["actions"][0]["subprocess"]["inputs"]["S1"] == {"value": "hello.pdf"}
177
+
178
+
179
+ def test_subprocess_no_literals_is_noop():
180
+ cfg = {"title": "sub", "variables": [{"name": "f", "model": "FileDataModel"}],
181
+ "actions": [{"id": "t", "action": "Call Subprocess", "subprocess": {
182
+ "target": "x", "inputs": {"S1": {"var": "f"}}, "outputs": {}}}]}
183
+ assert pb._hoist_subprocess_literals(cfg) is cfg # unchanged, same object