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,600 @@
1
+ """SQL Server engine-specific schema extraction + migration helpers.
2
+
3
+ Provides the driver-touching half of the `schema-extract`, `schema-diff`, and
4
+ `migrate` actions; the pure, engine-agnostic machinery (mirror layout, diff,
5
+ migration discovery / danger / GO split) lives in ``tools/_lib/dbschema.py``.
6
+
7
+ Every function here takes a connection-like object (a real pyodbc connection or
8
+ a test fake) and uses ``conn.cursor()`` directly. The extract path is read-only
9
+ (SELECT against the system catalog). The migrate path is the only writer and is
10
+ gated upstream behind ``--apply``.
11
+
12
+ A "record" is the shared dbschema shape:
13
+ {"type": <dir label>, "schema": <str|"">, "name": <str>, "definition": <sql>}
14
+
15
+ Object types extracted (by the ``sys.objects.type`` letter):
16
+ P procedures -> dir "Procedures" (verbatim sys.sql_modules)
17
+ FN scalar functions -> dir "Functions" (verbatim)
18
+ IF inline TVFs -> dir "Functions" (verbatim)
19
+ TF table-valued functions -> dir "Functions" (verbatim)
20
+ V views -> dir "Views" (verbatim)
21
+ TR DML triggers -> dir "Triggers" (verbatim)
22
+ U user tables -> dir "Tables" (DDL generated from catalog)
23
+
24
+ Module objects (P/FN/IF/TF/V/TR) come VERBATIM from ``sys.sql_modules.definition``
25
+ so the mirror is byte-faithful to what the server stores. Tables (U) have no stored
26
+ "CREATE TABLE" text, so their DDL is generated from the catalog: columns (type,
27
+ nullability, identity, default, collation, computed), primary key, foreign keys,
28
+ non-PK indexes, and check constraints.
29
+
30
+ DEFERRED (v1 — not blocking; port from a sibling schema extractor when needed):
31
+ - CLR assemblies (sys.assemblies) and CLR procs/types
32
+ - user-defined types: scalar alias / table types / CLR types
33
+ - authored schemas (CREATE SCHEMA) and database-scope DDL triggers
34
+ - partitioning / filegroups / XML schema collections / full-text / sequences
35
+ - synonyms, Service Broker objects, extended properties
36
+ """
37
+ from __future__ import annotations
38
+
39
+ from typing import Any
40
+
41
+ from tools._lib import dbquery, dbschema
42
+
43
+ # ---------------------------------------------------------------------------
44
+ # Type-letter -> readable directory label. The mirror groups objects by this
45
+ # label (dbschema.mirror_relpath uses it as the <Type> folder).
46
+ # ---------------------------------------------------------------------------
47
+
48
+ MODULE_TYPES = {
49
+ "P": "Procedures",
50
+ "FN": "Functions",
51
+ "IF": "Functions",
52
+ "TF": "Functions",
53
+ "V": "Views",
54
+ "TR": "Triggers",
55
+ }
56
+ TABLE_TYPE = "U"
57
+ TABLE_LABEL = "Tables"
58
+
59
+ # All type letters this engine knows how to extract.
60
+ ALL_TYPES = set(MODULE_TYPES) | {TABLE_TYPE}
61
+
62
+
63
+ # ---------------------------------------------------------------------------
64
+ # small cursor helpers
65
+ # ---------------------------------------------------------------------------
66
+
67
+ def _rows(cur) -> list[dict[str, Any]]:
68
+ """Materialise the current cursor result as a list of column->value dicts."""
69
+ cols = [c[0] for c in cur.description]
70
+ return [{cols[i]: r[i] for i in range(len(cols))} for r in cur.fetchall()]
71
+
72
+
73
+ def _normalize(text: str) -> str:
74
+ """Collapse CRLF/CR to LF so hashes are deterministic across hosts.
75
+
76
+ SQL Server returns ``sys.sql_modules.definition`` with CRLF line endings; on
77
+ Windows ``Path.write_text`` would translate ``\\n`` -> ``\\r\\n`` again,
78
+ producing ``\\r\\r\\n``. Normalising to LF here keeps the mirror clean and the
79
+ manifest sha stable (incremental runs short-circuit correctly).
80
+ """
81
+ return text.replace("\r\n", "\n").replace("\r", "\n")
82
+
83
+
84
+ # ---------------------------------------------------------------------------
85
+ # Module objects (procedures / functions / views / triggers) — verbatim
86
+ # ---------------------------------------------------------------------------
87
+
88
+ # One catalog query pulls every module definition. A LEFT JOIN to sys.sql_modules
89
+ # means encrypted (WITH ENCRYPTION) or permission-denied objects come back with a
90
+ # NULL body — surfaced as a comment placeholder rather than dropped silently.
91
+ _MODULES_SQL = """
92
+ SELECT
93
+ SCHEMA_NAME(o.schema_id) AS schema_name,
94
+ o.name AS object_name,
95
+ o.type AS type_code,
96
+ o.type_desc AS type_desc,
97
+ m.definition AS body
98
+ FROM sys.objects o
99
+ LEFT JOIN sys.sql_modules m ON m.object_id = o.object_id
100
+ WHERE o.type IN ('P','FN','TF','IF','V','TR')
101
+ AND o.is_ms_shipped = 0
102
+ ORDER BY SCHEMA_NAME(o.schema_id), o.name;
103
+ """
104
+
105
+
106
+ def _emit_module(obj: dict[str, Any]) -> str:
107
+ body = obj.get("body")
108
+ schema = obj.get("schema_name") or ""
109
+ name = obj.get("object_name")
110
+ if body is None:
111
+ return (
112
+ f"-- Object: {schema}.{name}\n"
113
+ f"-- Type: {obj.get('type_desc')}\n"
114
+ f"-- NOTE: definition unavailable (encrypted or permission denied)\n"
115
+ )
116
+ body = _normalize(body)
117
+ if not body.endswith("\n"):
118
+ body += "\n"
119
+ return body
120
+
121
+
122
+ def extract_modules(conn) -> list[dict[str, Any]]:
123
+ """Records for every P/FN/IF/TF/V/TR object, definition VERBATIM."""
124
+ cur = conn.cursor()
125
+ cur.execute(_MODULES_SQL)
126
+ out: list[dict[str, Any]] = []
127
+ for obj in _rows(cur):
128
+ code = (obj.get("type_code") or "").strip()
129
+ label = MODULE_TYPES.get(code)
130
+ if not label:
131
+ continue
132
+ out.append({
133
+ "type": label,
134
+ "schema": obj.get("schema_name") or "",
135
+ "name": obj.get("object_name"),
136
+ "definition": _emit_module(obj),
137
+ })
138
+ return out
139
+
140
+
141
+ # ---------------------------------------------------------------------------
142
+ # Tables — CREATE TABLE DDL generated from the catalog
143
+ # ---------------------------------------------------------------------------
144
+
145
+ _TABLES_SQL = """
146
+ SELECT
147
+ t.object_id,
148
+ SCHEMA_NAME(t.schema_id) AS schema_name,
149
+ t.name AS table_name
150
+ FROM sys.tables t
151
+ WHERE t.is_ms_shipped = 0
152
+ ORDER BY SCHEMA_NAME(t.schema_id), t.name;
153
+ """
154
+
155
+ _COLUMNS_SQL = """
156
+ SELECT
157
+ c.column_id,
158
+ c.name AS column_name,
159
+ TYPE_NAME(c.user_type_id) AS type_name,
160
+ c.max_length,
161
+ c.precision,
162
+ c.scale,
163
+ c.is_nullable,
164
+ c.is_identity,
165
+ CAST(ic.seed_value AS NVARCHAR(64)) AS seed_value,
166
+ CAST(ic.increment_value AS NVARCHAR(64)) AS increment_value,
167
+ c.collation_name,
168
+ cc.definition AS computed_definition,
169
+ cc.is_persisted,
170
+ dc.definition AS default_definition,
171
+ dc.name AS default_name,
172
+ c.is_computed
173
+ FROM sys.columns c
174
+ LEFT JOIN sys.identity_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
175
+ LEFT JOIN sys.computed_columns cc ON cc.object_id = c.object_id AND cc.column_id = c.column_id
176
+ LEFT JOIN sys.default_constraints dc
177
+ ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
178
+ WHERE c.object_id = ?
179
+ ORDER BY c.column_id;
180
+ """
181
+
182
+ _PK_SQL = """
183
+ SELECT
184
+ kc.name AS constraint_name,
185
+ i.type_desc,
186
+ c.name AS column_name,
187
+ ic.is_descending_key,
188
+ ic.key_ordinal
189
+ FROM sys.key_constraints kc
190
+ JOIN sys.indexes i ON i.object_id = kc.parent_object_id AND i.index_id = kc.unique_index_id
191
+ JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
192
+ JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
193
+ WHERE kc.parent_object_id = ? AND kc.type = 'PK'
194
+ ORDER BY kc.name, ic.key_ordinal;
195
+ """
196
+
197
+ _INDEX_SQL = """
198
+ SELECT
199
+ i.index_id,
200
+ i.name AS index_name,
201
+ i.type_desc,
202
+ i.is_unique,
203
+ i.filter_definition,
204
+ c.name AS column_name,
205
+ ic.is_descending_key,
206
+ ic.is_included_column,
207
+ ic.key_ordinal
208
+ FROM sys.indexes i
209
+ JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
210
+ JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
211
+ WHERE i.object_id = ?
212
+ AND i.is_primary_key = 0
213
+ AND i.is_unique_constraint = 0
214
+ AND i.type > 0
215
+ ORDER BY i.index_id, ic.is_included_column, ic.key_ordinal;
216
+ """
217
+
218
+ _FK_SQL = """
219
+ SELECT
220
+ fk.name AS fk_name,
221
+ SCHEMA_NAME(ref.schema_id) AS ref_schema,
222
+ ref.name AS ref_table,
223
+ pc.name AS parent_column,
224
+ rc.name AS ref_column,
225
+ fk.delete_referential_action_desc,
226
+ fk.update_referential_action_desc,
227
+ fkc.constraint_column_id
228
+ FROM sys.foreign_keys fk
229
+ JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
230
+ JOIN sys.columns pc ON pc.object_id = fkc.parent_object_id AND pc.column_id = fkc.parent_column_id
231
+ JOIN sys.columns rc ON rc.object_id = fkc.referenced_object_id AND rc.column_id = fkc.referenced_column_id
232
+ JOIN sys.tables ref ON ref.object_id = fk.referenced_object_id
233
+ WHERE fk.parent_object_id = ?
234
+ ORDER BY fk.name, fkc.constraint_column_id;
235
+ """
236
+
237
+ _CHECK_SQL = """
238
+ SELECT
239
+ cc.name AS constraint_name,
240
+ cc.definition AS definition,
241
+ cc.is_disabled
242
+ FROM sys.check_constraints cc
243
+ WHERE cc.parent_object_id = ?
244
+ ORDER BY cc.name;
245
+ """
246
+
247
+ _LENGTH_TYPES = {"varchar", "nvarchar", "char", "nchar", "varbinary", "binary"}
248
+ _PRECISION_TYPES = {"decimal", "numeric"}
249
+ _SCALE_TYPES = {"datetime2", "time", "datetimeoffset"}
250
+ _COLLATABLE = {"varchar", "nvarchar", "char", "nchar", "text", "ntext"}
251
+
252
+
253
+ def _format_type(type_name: str, max_length, precision, scale) -> str:
254
+ t = (type_name or "").lower()
255
+ if t in _LENGTH_TYPES:
256
+ if max_length == -1:
257
+ return f"{t}(MAX)"
258
+ chars = max_length // 2 if t.startswith("n") else max_length
259
+ return f"{t}({chars})"
260
+ if t in _PRECISION_TYPES:
261
+ return f"{t}({precision}, {scale})"
262
+ if t in _SCALE_TYPES:
263
+ return f"{t}({scale})"
264
+ return t
265
+
266
+
267
+ def _qname(schema: str, name: str) -> str:
268
+ return f"[{schema}].[{name}]"
269
+
270
+
271
+ def _emit_table(conn, obj: dict[str, Any]) -> str:
272
+ oid = obj["object_id"]
273
+ schema = obj["schema_name"]
274
+ name = obj["table_name"]
275
+ cur = conn.cursor()
276
+
277
+ cur.execute(_COLUMNS_SQL, oid)
278
+ columns = _rows(cur)
279
+ cur.execute(_PK_SQL, oid)
280
+ pk_rows = _rows(cur)
281
+ cur.execute(_INDEX_SQL, oid)
282
+ idx_rows = _rows(cur)
283
+ cur.execute(_FK_SQL, oid)
284
+ fk_rows = _rows(cur)
285
+ cur.execute(_CHECK_SQL, oid)
286
+ ck_rows = _rows(cur)
287
+
288
+ lines: list[str] = [f"CREATE TABLE {_qname(schema, name)} ("]
289
+ col_defs: list[str] = []
290
+ for c in columns:
291
+ if c.get("is_computed") and c.get("computed_definition"):
292
+ persist = " PERSISTED" if c.get("is_persisted") else ""
293
+ col_defs.append(f" [{c['column_name']}] AS {c['computed_definition']}{persist}")
294
+ continue
295
+ type_str = _format_type(c["type_name"], c["max_length"], c["precision"], c["scale"])
296
+ ident = ""
297
+ if c.get("is_identity"):
298
+ ident = f" IDENTITY({c.get('seed_value')},{c.get('increment_value')})"
299
+ nullable = "NULL" if c.get("is_nullable") else "NOT NULL"
300
+ default = ""
301
+ if c.get("default_definition"):
302
+ default = f" CONSTRAINT [{c['default_name']}] DEFAULT {c['default_definition']}"
303
+ coll = ""
304
+ if c.get("collation_name") and (c["type_name"] or "").lower() in _COLLATABLE:
305
+ coll = f" COLLATE {c['collation_name']}"
306
+ col_defs.append(
307
+ f" [{c['column_name']}] {type_str}{coll}{ident} {nullable}{default}"
308
+ )
309
+
310
+ if pk_rows:
311
+ pk_name = pk_rows[0]["constraint_name"]
312
+ pk_type = "CLUSTERED" if pk_rows[0]["type_desc"] == "CLUSTERED" else "NONCLUSTERED"
313
+ pk_cols = ", ".join(
314
+ f"[{r['column_name']}]{' DESC' if r.get('is_descending_key') else ''}"
315
+ for r in pk_rows
316
+ )
317
+ col_defs.append(f" CONSTRAINT [{pk_name}] PRIMARY KEY {pk_type} ({pk_cols})")
318
+
319
+ lines.append(",\n".join(col_defs))
320
+ lines.append(");")
321
+ lines.append("GO")
322
+
323
+ # CHECK constraints
324
+ for ck in ck_rows:
325
+ dis = " WITH NOCHECK" if ck.get("is_disabled") else ""
326
+ lines.append(
327
+ f"ALTER TABLE {_qname(schema, name)}{dis} "
328
+ f"ADD CONSTRAINT [{ck['constraint_name']}] CHECK {ck['definition']};"
329
+ )
330
+ lines.append("GO")
331
+
332
+ # Non-PK indexes
333
+ if idx_rows:
334
+ by_idx: dict[Any, list[dict]] = {}
335
+ for r in idx_rows:
336
+ by_idx.setdefault(r["index_id"], []).append(r)
337
+ for entries in by_idx.values():
338
+ ix = entries[0]
339
+ keys = sorted(
340
+ (e for e in entries if not e.get("is_included_column")),
341
+ key=lambda e: e["key_ordinal"],
342
+ )
343
+ incs = [e for e in entries if e.get("is_included_column")]
344
+ unique = "UNIQUE " if ix.get("is_unique") else ""
345
+ key_cols = ", ".join(
346
+ f"[{e['column_name']}]{' DESC' if e.get('is_descending_key') else ''}"
347
+ for e in keys
348
+ )
349
+ include = ""
350
+ if incs:
351
+ include = " INCLUDE (" + ", ".join(f"[{e['column_name']}]" for e in incs) + ")"
352
+ where = f" WHERE {ix['filter_definition']}" if ix.get("filter_definition") else ""
353
+ lines.append(
354
+ f"CREATE {unique}{ix['type_desc']} INDEX [{ix['index_name']}] "
355
+ f"ON {_qname(schema, name)} ({key_cols}){include}{where};"
356
+ )
357
+ lines.append("GO")
358
+
359
+ # Foreign keys
360
+ if fk_rows:
361
+ by_fk: dict[str, list[dict]] = {}
362
+ for r in fk_rows:
363
+ by_fk.setdefault(r["fk_name"], []).append(r)
364
+ for fk_name, entries in by_fk.items():
365
+ entries.sort(key=lambda e: e["constraint_column_id"])
366
+ head = entries[0]
367
+ parent_cols = ", ".join(f"[{e['parent_column']}]" for e in entries)
368
+ ref_cols = ", ".join(f"[{e['ref_column']}]" for e in entries)
369
+ on_del = (
370
+ f" ON DELETE {head['delete_referential_action_desc'].replace('_', ' ')}"
371
+ if head.get("delete_referential_action_desc") not in (None, "NO_ACTION") else ""
372
+ )
373
+ on_upd = (
374
+ f" ON UPDATE {head['update_referential_action_desc'].replace('_', ' ')}"
375
+ if head.get("update_referential_action_desc") not in (None, "NO_ACTION") else ""
376
+ )
377
+ lines.append(
378
+ f"ALTER TABLE {_qname(schema, name)} "
379
+ f"ADD CONSTRAINT [{fk_name}] FOREIGN KEY ({parent_cols}) "
380
+ f"REFERENCES {_qname(head['ref_schema'], head['ref_table'])} "
381
+ f"({ref_cols}){on_del}{on_upd};"
382
+ )
383
+ lines.append("GO")
384
+
385
+ return "\n".join(lines) + "\n"
386
+
387
+
388
+ def extract_tables(conn) -> list[dict[str, Any]]:
389
+ """Records for every user table, DDL generated from the catalog."""
390
+ cur = conn.cursor()
391
+ cur.execute(_TABLES_SQL)
392
+ tables = _rows(cur)
393
+ out: list[dict[str, Any]] = []
394
+ for obj in tables:
395
+ out.append({
396
+ "type": TABLE_LABEL,
397
+ "schema": obj.get("schema_name") or "",
398
+ "name": obj.get("table_name"),
399
+ "definition": _emit_table(conn, obj),
400
+ })
401
+ return out
402
+
403
+
404
+ # ---------------------------------------------------------------------------
405
+ # Public extract entrypoint
406
+ # ---------------------------------------------------------------------------
407
+
408
+ def extract_objects(conn, types=None) -> list[dict[str, Any]]:
409
+ """Extract all (or a filtered subset of) DB objects as dbschema records.
410
+
411
+ `types` is an optional iterable of SQL Server type letters to keep
412
+ (``P``, ``FN``, ``TF``, ``IF``, ``V``, ``TR``, ``U``). ``None`` extracts all.
413
+ The connection is autocommit + read-only; only SELECTs against the catalog
414
+ are issued. Returns records sorted for a stable mirror.
415
+ """
416
+ wanted = None
417
+ if types is not None:
418
+ wanted = {t.strip().upper() for t in types if t and t.strip()}
419
+
420
+ records: list[dict[str, Any]] = []
421
+ want_modules = wanted is None or (wanted & set(MODULE_TYPES))
422
+ if want_modules:
423
+ for rec in extract_modules(conn):
424
+ # filter at the type-letter level when a subset was requested
425
+ if wanted is not None:
426
+ # map back: the dir label alone is ambiguous (Functions <- FN/IF/TF),
427
+ # so re-derive whether this record's letter is wanted by re-running
428
+ # is unnecessary — extract_modules already only yields known labels;
429
+ # filtering by letter happens below via _module_letter_wanted.
430
+ pass
431
+ records.append(rec)
432
+ if wanted is not None:
433
+ records = [r for r in records if _record_letters_wanted(r, wanted)]
434
+
435
+ if wanted is None or TABLE_TYPE in wanted:
436
+ records.extend(extract_tables(conn))
437
+
438
+ records.sort(key=lambda r: (r["type"], r.get("schema") or "", r["name"]))
439
+ return records
440
+
441
+
442
+ # Reverse map label -> set of letters that can produce it, for --types filtering.
443
+ _LABEL_LETTERS: dict[str, set[str]] = {}
444
+ for _letter, _label in MODULE_TYPES.items():
445
+ _LABEL_LETTERS.setdefault(_label, set()).add(_letter)
446
+ _LABEL_LETTERS[TABLE_LABEL] = {TABLE_TYPE}
447
+
448
+
449
+ def _record_letters_wanted(record: dict, wanted: set[str]) -> bool:
450
+ """True if the record's dir label maps to at least one wanted type letter.
451
+
452
+ "Functions" maps to {FN, IF, TF}; if the user asked for only ``TF`` we cannot
453
+ distinguish from the label alone, so we keep the whole Functions group when
454
+ ANY of its letters is wanted. This is the documented coarse behaviour: --types
455
+ selects object FAMILIES (proc / function / view / trigger / table), not the
456
+ sub-kinds of a family.
457
+ """
458
+ letters = _LABEL_LETTERS.get(record["type"], set())
459
+ return bool(letters & wanted)
460
+
461
+
462
+ # ===========================================================================
463
+ # Migration engine
464
+ # ===========================================================================
465
+
466
+ MIGRATIONS_SCHEMA = "dbo"
467
+ MIGRATIONS_TABLE = "__schema_migrations"
468
+ MIG_FQN = f"[{MIGRATIONS_SCHEMA}].[{MIGRATIONS_TABLE}]"
469
+
470
+ _ENSURE_TABLE_SQL = f"""
471
+ IF NOT EXISTS (
472
+ SELECT 1 FROM sys.tables t JOIN sys.schemas s ON s.schema_id = t.schema_id
473
+ WHERE t.name = '{MIGRATIONS_TABLE}' AND s.name = '{MIGRATIONS_SCHEMA}'
474
+ )
475
+ BEGIN
476
+ CREATE TABLE {MIG_FQN} (
477
+ migration_id NVARCHAR(200) NOT NULL
478
+ CONSTRAINT PK___schema_migrations PRIMARY KEY,
479
+ filename NVARCHAR(260) NOT NULL,
480
+ sha256 NCHAR(64) NOT NULL,
481
+ applied_at DATETIME2(0) NOT NULL
482
+ CONSTRAINT DF___schema_migrations_applied_at DEFAULT SYSUTCDATETIME(),
483
+ applied_by NVARCHAR(128) NOT NULL
484
+ CONSTRAINT DF___schema_migrations_applied_by DEFAULT SUSER_SNAME(),
485
+ duration_ms INT NULL,
486
+ notes NVARCHAR(MAX) NULL
487
+ );
488
+ END;
489
+ """
490
+
491
+
492
+ def ensure_migrations_table(conn) -> None:
493
+ """Create ``dbo.__schema_migrations`` if it does not already exist. This is a
494
+ WRITE — only the ``apply`` path calls it; ``list`` stays read-only."""
495
+ cur = conn.cursor()
496
+ cur.execute(_ENSURE_TABLE_SQL)
497
+
498
+
499
+ def tracking_table_exists(conn) -> bool:
500
+ """Read-only: does the tracking table exist? (never creates it)."""
501
+ cur = conn.cursor()
502
+ cur.execute(
503
+ "SELECT 1 FROM sys.tables t JOIN sys.schemas s ON s.schema_id = t.schema_id "
504
+ "WHERE t.name = ? AND s.name = ?", (MIGRATIONS_TABLE, MIGRATIONS_SCHEMA))
505
+ return cur.fetchone() is not None
506
+
507
+
508
+ def fetch_applied(conn) -> dict[str, dict[str, Any]]:
509
+ """Return {migration_id: {sha256, filename, applied_at}} from the tracking table.
510
+
511
+ READ-ONLY: if the tracking table does not exist yet, returns {} WITHOUT
512
+ creating it (only ``apply`` creates the table).
513
+ """
514
+ if not tracking_table_exists(conn):
515
+ return {}
516
+ cur = conn.cursor()
517
+ cur.execute(
518
+ f"SELECT migration_id, sha256, filename, applied_at FROM {MIG_FQN}"
519
+ )
520
+ out: dict[str, dict[str, Any]] = {}
521
+ for row in cur.fetchall():
522
+ # Support both pyodbc Row (attribute access) and plain tuples (test fakes).
523
+ if hasattr(row, "migration_id"):
524
+ mid = row.migration_id
525
+ out[mid] = {
526
+ "sha256": row.sha256,
527
+ "filename": row.filename,
528
+ "applied_at": _to_str(row.applied_at),
529
+ }
530
+ else:
531
+ mid = row[0]
532
+ out[mid] = {
533
+ "sha256": row[1],
534
+ "filename": row[2],
535
+ "applied_at": _to_str(row[3]),
536
+ }
537
+ return out
538
+
539
+
540
+ def _to_str(value) -> Any:
541
+ """JSON-safe scalar (datetimes -> isoformat, else passthrough)."""
542
+ if value is None:
543
+ return None
544
+ if hasattr(value, "isoformat"):
545
+ return value.isoformat()
546
+ return value
547
+
548
+
549
+ def record_applied(conn, mig_id: str, filename: str, sha: str,
550
+ duration_ms: int | None = None) -> None:
551
+ """Insert a tracking row for a successfully applied migration."""
552
+ cur = conn.cursor()
553
+ cur.execute(
554
+ f"INSERT INTO {MIG_FQN} (migration_id, filename, sha256, duration_ms) "
555
+ f"VALUES (?, ?, ?, ?)",
556
+ (mig_id, filename, sha, duration_ms),
557
+ )
558
+
559
+
560
+ def apply_migration_sql(conn, sql: str, *, dry_run: bool = False) -> int:
561
+ """Execute one migration's SQL inside a SINGLE transaction for the file.
562
+
563
+ The SQL is split into GO batches (``dbschema.split_go_batches``); each batch
564
+ runs via ``cursor.execute``. Our connection is autocommit=True, so we open an
565
+ explicit transaction with ``BEGIN TRAN`` and either ``COMMIT`` (apply) or
566
+ ``ROLLBACK`` (dry-run / on error) — giving file-level atomicity and a no-op
567
+ validation mode.
568
+
569
+ Returns the number of batches executed. Re-raises on the first batch error
570
+ after rolling the file's transaction back.
571
+
572
+ Known limitation: ``split_go_batches`` splits on any line that is exactly
573
+ ``GO`` — a ``GO`` alone on a line inside a string literal or block comment is
574
+ still treated as a batch separator (documented in dbschema.split_go_batches).
575
+ """
576
+ batches = dbschema.split_go_batches(sql)
577
+ cur = conn.cursor()
578
+ cur.execute("SET XACT_ABORT ON; BEGIN TRANSACTION;")
579
+ executed = 0
580
+ try:
581
+ for batch in batches:
582
+ if not batch.strip():
583
+ continue
584
+ cur.execute(batch)
585
+ # A statement that fails after one that returned "N rows affected" raises only
586
+ # when the cursor reaches it. Undrained, XACT_ABORT rolls the file back on the
587
+ # server while this side commits nothing and reports the migration as applied.
588
+ dbquery.drain_results(cur)
589
+ executed += 1
590
+ except Exception:
591
+ try:
592
+ cur.execute("IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;")
593
+ except Exception: # noqa: BLE001
594
+ pass
595
+ raise
596
+ if dry_run:
597
+ cur.execute("IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;")
598
+ else:
599
+ cur.execute("IF @@TRANCOUNT > 0 COMMIT TRANSACTION;")
600
+ return executed
File without changes
@@ -0,0 +1,21 @@
1
+ """Put the framework root on sys.path so `from tools...` imports work."""
2
+ from __future__ import annotations
3
+
4
+ import sys
5
+ from pathlib import Path
6
+ import pytest
7
+
8
+ # pyodbc is an OPTIONAL dependency (the SQL Server driver), so a plain install does not
9
+ # have it. These tests then FAIL, which reads as a broken repository rather
10
+ # than as an extra nobody asked for. Skip instead, with the reason visible.
11
+ #
12
+ # exc_type matters: pytest 9 skips only on ModuleNotFoundError by default,
13
+ # and a package can be installed yet unimportable - pyodbc on a runner
14
+ # without its native library raises a plain ImportError, which would
15
+ # otherwise re-raise and take collection down instead of skipping.
16
+ pytest.importorskip('pyodbc', reason="install the extra that provides pyodbc",
17
+ exc_type=ImportError)
18
+
19
+ FRAMEWORK_ROOT = Path(__file__).resolve().parents[3]
20
+ if str(FRAMEWORK_ROOT) not in sys.path:
21
+ sys.path.insert(0, str(FRAMEWORK_ROOT))