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,488 @@
1
+ """Tests for the sqlserver schema-extract / schema-diff / migrate actions.
2
+
3
+ No live DB and no pyodbc: extraction runs against a FAKE cursor returning canned
4
+ catalog rows, dispatch injects a ``conn_factory``, and the diff dir-vs-dir path
5
+ needs no connection at all. The migrate ``list`` path uses a fake connection that
6
+ returns canned applied rows; the apply-without-``--apply`` guard is asserted.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import pytest
11
+
12
+ from tools._lib import dbschema
13
+ from tools.sqlserver import main, schema
14
+
15
+
16
+ # --- programmable fake cursor/connection ------------------------------------
17
+
18
+ class FakeCursor:
19
+ """Replays a queue of (description, rows) results across execute() calls.
20
+
21
+ Each execute() advances to the next queued result; description/fetchall
22
+ reflect the most recent execute. This models pyodbc's behaviour where the
23
+ same cursor is reused for several queries (as schema._emit_table does).
24
+ """
25
+
26
+ def __init__(self, results):
27
+ self._results = list(results) # list[(description, rows)]
28
+ self._i = -1
29
+ self.executed = []
30
+
31
+ def execute(self, sql, *params):
32
+ self.executed.append((sql, params))
33
+ if self._i + 1 < len(self._results):
34
+ self._i += 1
35
+
36
+ @property
37
+ def description(self):
38
+ if self._i < 0:
39
+ return None
40
+ return self._results[self._i][0]
41
+
42
+ def fetchall(self):
43
+ if self._i < 0:
44
+ return []
45
+ return list(self._results[self._i][1])
46
+
47
+ def fetchone(self):
48
+ rows = self.fetchall()
49
+ return rows[0] if rows else None
50
+
51
+ def close(self):
52
+ pass
53
+
54
+
55
+ class FakeConn:
56
+ """Hands out a queued cursor on each .cursor() call."""
57
+
58
+ def __init__(self, cursor_queue):
59
+ self._queue = list(cursor_queue)
60
+ self.cursors = []
61
+ self.closed = False
62
+
63
+ def cursor(self):
64
+ cur = self._queue.pop(0)
65
+ self.cursors.append(cur)
66
+ return cur
67
+
68
+ def close(self):
69
+ self.closed = True
70
+
71
+
72
+ def _desc(*names):
73
+ return [(n, None) for n in names]
74
+
75
+
76
+ # --- a profile must exist for needs_conn actions ----------------------------
77
+
78
+ @pytest.fixture
79
+ def one_profile(tmp_path, monkeypatch):
80
+ from tools._lib import dbprofiles
81
+
82
+ pfile = tmp_path / "profiles.json"
83
+ monkeypatch.setattr(main, "PROFILES_PATH", pfile)
84
+ monkeypatch.setattr(dbprofiles.creds, "has", lambda *a: False)
85
+ monkeypatch.setattr(dbprofiles.creds, "get_optional", lambda *a: None)
86
+ main._store().add("default", {"server": "h", "database": "d", "username": "u"})
87
+ return pfile
88
+
89
+
90
+ # ===========================================================================
91
+ # extract_objects against a fake cursor
92
+ # ===========================================================================
93
+
94
+ # canned module rows: a proc, a scalar function, a view, a trigger, plus an
95
+ # is_ms_shipped-style row already excluded by SQL, and an encrypted (NULL body).
96
+ _MODULE_DESC = _desc("schema_name", "object_name", "type_code", "type_desc", "body")
97
+ _MODULE_ROWS = [
98
+ ("dbo", "GetCustomer", "P ", "SQL_STORED_PROCEDURE",
99
+ "CREATE PROCEDURE dbo.GetCustomer AS SELECT 1\r\n"),
100
+ ("dbo", "fnTax", "FN", "SQL_SCALAR_FUNCTION",
101
+ "CREATE FUNCTION dbo.fnTax() RETURNS int AS BEGIN RETURN 1 END"),
102
+ ("dbo", "vCustomer", "V", "VIEW", "CREATE VIEW dbo.vCustomer AS SELECT 1 AS x"),
103
+ ("dbo", "trAudit", "TR", "SQL_TRIGGER", "CREATE TRIGGER dbo.trAudit ON dbo.t AFTER INSERT AS SELECT 1"),
104
+ ("dbo", "secret", "P", "SQL_STORED_PROCEDURE", None), # encrypted -> NULL body
105
+ ]
106
+
107
+
108
+ def _modules_only_conn():
109
+ return FakeConn([FakeCursor([(_MODULE_DESC, _MODULE_ROWS)])])
110
+
111
+
112
+ def test_extract_modules_verbatim_and_labels():
113
+ recs = schema.extract_modules(_modules_only_conn())
114
+ by_name = {r["name"]: r for r in recs}
115
+ assert by_name["GetCustomer"]["type"] == "Procedures"
116
+ assert by_name["fnTax"]["type"] == "Functions"
117
+ assert by_name["vCustomer"]["type"] == "Views"
118
+ assert by_name["trAudit"]["type"] == "Triggers"
119
+ # CRLF normalised to LF, verbatim body preserved
120
+ assert by_name["GetCustomer"]["definition"] == "CREATE PROCEDURE dbo.GetCustomer AS SELECT 1\n"
121
+ # encrypted object surfaces a NOTE placeholder rather than being dropped
122
+ assert "definition unavailable" in by_name["secret"]["definition"]
123
+
124
+
125
+ # --- table DDL generation ---------------------------------------------------
126
+
127
+ _TABLES_DESC = _desc("object_id", "schema_name", "table_name")
128
+ _TABLES_ROWS = [(10, "dbo", "Customer")]
129
+
130
+ _COLUMNS_DESC = _desc(
131
+ "column_id", "column_name", "type_name", "max_length", "precision", "scale",
132
+ "is_nullable", "is_identity", "seed_value", "increment_value", "collation_name",
133
+ "computed_definition", "is_persisted", "default_definition", "default_name",
134
+ "is_computed",
135
+ )
136
+ _COLUMNS_ROWS = [
137
+ # Id INT IDENTITY(1,1) NOT NULL
138
+ (1, "Id", "int", 4, 10, 0, 0, 1, "1", "1", None, None, 0, None, None, 0),
139
+ # Name nvarchar(100) NOT NULL with a default
140
+ (2, "Name", "nvarchar", 200, 0, 0, 0, 0, None, None, "Latin1_General_CI_AS",
141
+ None, 0, "('x')", "DF_Customer_Name", 0),
142
+ # Notes nvarchar(MAX) NULL
143
+ (3, "Notes", "nvarchar", -1, 0, 0, 1, 0, None, None, "Latin1_General_CI_AS",
144
+ None, 0, None, None, 0),
145
+ ]
146
+
147
+ _PK_DESC = _desc("constraint_name", "type_desc", "column_name", "is_descending_key", "key_ordinal")
148
+ _PK_ROWS = [("PK_Customer", "CLUSTERED", "Id", 0, 1)]
149
+
150
+ _INDEX_DESC = _desc("index_id", "index_name", "type_desc", "is_unique",
151
+ "filter_definition", "column_name", "is_descending_key",
152
+ "is_included_column", "key_ordinal")
153
+ _INDEX_ROWS = [(2, "IX_Customer_Name", "NONCLUSTERED", 0, None, "Name", 0, 0, 1)]
154
+
155
+ _FK_DESC = _desc("fk_name", "ref_schema", "ref_table", "parent_column", "ref_column",
156
+ "delete_referential_action_desc", "update_referential_action_desc",
157
+ "constraint_column_id")
158
+ _FK_ROWS = [("FK_Customer_Region", "dbo", "Region", "RegionId", "Id",
159
+ "NO_ACTION", "NO_ACTION", 1)]
160
+
161
+ _CHECK_DESC = _desc("constraint_name", "definition", "is_disabled")
162
+ _CHECK_ROWS = []
163
+
164
+
165
+ def _tables_conn():
166
+ # extract_tables: 1 cursor for the TABLES list, then one cursor reused for the
167
+ # five per-table queries (columns, pk, index, fk, check).
168
+ tables_cur = FakeCursor([(_TABLES_DESC, _TABLES_ROWS)])
169
+ table_detail_cur = FakeCursor([
170
+ (_COLUMNS_DESC, _COLUMNS_ROWS),
171
+ (_PK_DESC, _PK_ROWS),
172
+ (_INDEX_DESC, _INDEX_ROWS),
173
+ (_FK_DESC, _FK_ROWS),
174
+ (_CHECK_DESC, _CHECK_ROWS),
175
+ ])
176
+ return FakeConn([tables_cur, table_detail_cur])
177
+
178
+
179
+ def test_extract_tables_generates_create_ddl():
180
+ recs = schema.extract_tables(_tables_conn())
181
+ assert len(recs) == 1
182
+ rec = recs[0]
183
+ assert rec["type"] == "Tables"
184
+ assert rec["schema"] == "dbo" and rec["name"] == "Customer"
185
+ ddl = rec["definition"]
186
+ assert "CREATE TABLE [dbo].[Customer]" in ddl
187
+ assert "[Id] int IDENTITY(1,1) NOT NULL" in ddl
188
+ assert "[Name] nvarchar(100)" in ddl # 200 bytes / 2 = 100 chars
189
+ # nvarchar(MAX), nullable, with collation between type and nullability
190
+ assert "[Notes] nvarchar(MAX)" in ddl
191
+ assert "[Notes] nvarchar(MAX) COLLATE Latin1_General_CI_AS NULL" in ddl
192
+ assert "CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED ([Id])" in ddl
193
+ assert "CREATE NONCLUSTERED INDEX [IX_Customer_Name]" in ddl
194
+ assert "ADD CONSTRAINT [FK_Customer_Region] FOREIGN KEY ([RegionId])" in ddl
195
+ assert "REFERENCES [dbo].[Region] ([Id])" in ddl
196
+
197
+
198
+ def test_extract_objects_types_filter_modules_only():
199
+ # only modules cursor needed when U is excluded
200
+ recs = schema.extract_objects(_modules_only_conn(), types=["P", "V"])
201
+ labels = {r["type"] for r in recs}
202
+ # Procedures + Views kept; Functions/Triggers dropped by the family filter
203
+ assert "Procedures" in labels and "Views" in labels
204
+ assert "Functions" not in labels and "Triggers" not in labels
205
+ assert "Tables" not in labels
206
+
207
+
208
+ # ===========================================================================
209
+ # schema-extract dispatch -> writes a mirror under tmp_path
210
+ # ===========================================================================
211
+
212
+ def test_dispatch_schema_extract_writes_mirror(one_profile, tmp_path):
213
+ out = tmp_path / "mirror"
214
+ conn = _modules_only_conn()
215
+ result = main.dispatch(
216
+ "schema-extract",
217
+ ["--profile", "default", "--types", "P,V,FN,TR", "--out", str(out)],
218
+ conn_factory=lambda _p: conn,
219
+ )
220
+ assert result["profile"] == "default"
221
+ # proc, fn, view, trigger + the encrypted "secret" proc (NULL body -> NOTE placeholder,
222
+ # still a record). --types P,V,FN,TR keeps all 5 module objects.
223
+ assert result["written"] == 5
224
+ assert (out / "_manifest.json").is_file()
225
+ proc = out / "schema" / "Procedures" / "dbo.GetCustomer.sql"
226
+ assert proc.is_file()
227
+ assert proc.read_text(encoding="utf-8").startswith("CREATE PROCEDURE")
228
+ assert conn.closed is True
229
+
230
+
231
+ def test_dispatch_schema_extract_dry_run_writes_nothing(one_profile, tmp_path):
232
+ out = tmp_path / "mirror"
233
+ result = main.dispatch(
234
+ "schema-extract",
235
+ ["--profile", "default", "--types", "P", "--out", str(out), "--dry-run"],
236
+ conn_factory=lambda _p: _modules_only_conn(),
237
+ )
238
+ assert result["dry_run"] is True
239
+ assert not out.exists()
240
+
241
+
242
+ # ===========================================================================
243
+ # schema-diff dir-vs-dir (no DB)
244
+ # ===========================================================================
245
+
246
+ def _make_mirror(root, files):
247
+ schema_root = root / "schema"
248
+ for rel, text in files.items():
249
+ p = schema_root / rel
250
+ p.parent.mkdir(parents=True, exist_ok=True)
251
+ p.write_text(text, encoding="utf-8")
252
+
253
+
254
+ def test_dispatch_schema_diff_dirs(tmp_path):
255
+ left = tmp_path / "left"
256
+ right = tmp_path / "right"
257
+ _make_mirror(left, {
258
+ "Procedures/dbo.A.sql": "CREATE PROC A AS SELECT 1\n",
259
+ "Views/dbo.Gone.sql": "CREATE VIEW Gone AS SELECT 1\n",
260
+ })
261
+ _make_mirror(right, {
262
+ "Procedures/dbo.A.sql": "CREATE PROC A AS SELECT 2\n", # changed
263
+ "Views/dbo.New.sql": "CREATE VIEW New AS SELECT 1\n", # added
264
+ })
265
+ result = main.dispatch("schema-diff", ["--left", str(left), "--right", str(right)])
266
+ assert result["summary"] == {"added": 1, "removed": 1, "changed": 1}
267
+ assert "schema/Views/dbo.New.sql" in result["added"]
268
+ assert "schema/Views/dbo.Gone.sql" in result["removed"]
269
+ assert result["changed"][0]["relpath"] == "schema/Procedures/dbo.A.sql"
270
+ assert "diff" in result["changed"][0] # unified diff present by default
271
+
272
+
273
+ def test_dispatch_schema_diff_no_diff_text(tmp_path):
274
+ left = tmp_path / "l"
275
+ right = tmp_path / "r"
276
+ _make_mirror(left, {"Procedures/dbo.A.sql": "x\n"})
277
+ _make_mirror(right, {"Procedures/dbo.A.sql": "y\n"})
278
+ result = main.dispatch(
279
+ "schema-diff",
280
+ ["--left", str(left), "--right", str(right), "--no-diff-text"],
281
+ )
282
+ assert result["changed"][0]["relpath"] == "schema/Procedures/dbo.A.sql"
283
+ assert "diff" not in result["changed"][0]
284
+
285
+
286
+ def test_dispatch_schema_diff_profile_side_extracts(one_profile, tmp_path):
287
+ # left is a live profile (extracted via the fake cursor), right is an empty dir
288
+ right = tmp_path / "right"
289
+ (right / "schema").mkdir(parents=True)
290
+ result = main.dispatch(
291
+ "schema-diff",
292
+ ["--left", "profile:default", "--right", str(right), "--types", "P,V,FN,TR"],
293
+ conn_factory=lambda _p: _modules_only_conn(),
294
+ )
295
+ # everything in the extracted left is "removed" relative to the empty right
296
+ assert result["summary"]["added"] == 0
297
+ assert result["summary"]["removed"] >= 4
298
+
299
+
300
+ # ===========================================================================
301
+ # migrate
302
+ # ===========================================================================
303
+
304
+ class MigrateConn:
305
+ """Fake connection for migrate: ensure-table is a no-op execute, then a SELECT
306
+ on the tracking table returns canned applied rows."""
307
+
308
+ def __init__(self, applied_rows, exists=True):
309
+ self._applied_rows = applied_rows
310
+ self._exists = exists
311
+ self.executed = []
312
+
313
+ def cursor(self):
314
+ return self # the conn is its own cursor for simplicity
315
+
316
+ def execute(self, sql, *params):
317
+ self.executed.append((sql, params))
318
+ self._last = sql
319
+
320
+ def fetchall(self):
321
+ if "SELECT migration_id" in self._last:
322
+ return list(self._applied_rows)
323
+ return []
324
+
325
+ def fetchone(self):
326
+ # tracking_table_exists probes sys.tables; report existence per self._exists.
327
+ if "sys.tables" in self._last:
328
+ return (1,) if self._exists else None
329
+ return None
330
+
331
+ def close(self):
332
+ pass
333
+
334
+
335
+ def _write_migrations(d, files):
336
+ d.mkdir(parents=True, exist_ok=True)
337
+ for name, text in files.items():
338
+ (d / name).write_text(text, encoding="utf-8")
339
+
340
+
341
+ def test_migrate_list_applied_and_pending(one_profile, tmp_path):
342
+ mig_dir = tmp_path / "migrations"
343
+ _write_migrations(mig_dir, {
344
+ "001_init.sql": "CREATE TABLE dbo.A (id int);\n",
345
+ "002_drop.sql": "DROP TABLE dbo.A;\n",
346
+ })
347
+ # 001 already applied (matching sha so no drift); 002 pending
348
+ sha001 = dbschema.sha256_file(mig_dir / "001_init.sql")
349
+ applied = [("001_init", sha001, "001_init.sql", "2026-01-01T00:00:00")]
350
+ result = main.dispatch(
351
+ "migrate",
352
+ ["--profile", "default", "--dir", str(mig_dir), "--mode", "list"],
353
+ conn_factory=lambda _p: MigrateConn(applied),
354
+ )
355
+ assert result["mode"] == "list"
356
+ assert [a["migration_id"] for a in result["applied"]] == ["001_init"]
357
+ assert [p["migration_id"] for p in result["pending"]] == ["002_drop"]
358
+ assert result["drift"] == []
359
+ # the pending DROP migration carries a danger warning
360
+ assert any("destructive" in w for w in result["pending"][0]["danger_warnings"])
361
+
362
+
363
+ def test_migrate_list_is_read_only_even_without_tracking_table(one_profile, tmp_path):
364
+ """`list` must NEVER create the tracking table (read-only on production DBs)."""
365
+ mig_dir = tmp_path / "migrations"
366
+ _write_migrations(mig_dir, {"001_init.sql": "SELECT 1;\n"})
367
+ conn = MigrateConn([], exists=False) # tracking table does not exist
368
+ result = main.dispatch(
369
+ "migrate", ["--profile", "default", "--dir", str(mig_dir), "--mode", "list"],
370
+ conn_factory=lambda _p: conn)
371
+ assert result["applied"] == [] and len(result["pending"]) == 1
372
+ assert not any("CREATE TABLE" in sql.upper() for sql, _ in conn.executed)
373
+
374
+
375
+ def test_migrate_list_detects_drift(one_profile, tmp_path):
376
+ mig_dir = tmp_path / "migrations"
377
+ _write_migrations(mig_dir, {"001_init.sql": "SELECT 1;\n"})
378
+ applied = [("001_init", "deadbeef" * 8, "001_init.sql", "2026-01-01T00:00:00")]
379
+ result = main.dispatch(
380
+ "migrate",
381
+ ["--profile", "default", "--dir", str(mig_dir), "--mode", "list"],
382
+ conn_factory=lambda _p: MigrateConn(applied),
383
+ )
384
+ assert len(result["drift"]) == 1
385
+ assert result["drift"][0]["migration_id"] == "001_init"
386
+
387
+
388
+ def test_migrate_apply_requires_apply_flag(one_profile, tmp_path):
389
+ mig_dir = tmp_path / "migrations"
390
+ _write_migrations(mig_dir, {"001_init.sql": "SELECT 1;\n"})
391
+ with pytest.raises(main.UsageError, match="--apply"):
392
+ main.dispatch(
393
+ "migrate",
394
+ ["--profile", "default", "--dir", str(mig_dir), "--mode", "apply"],
395
+ conn_factory=lambda _p: MigrateConn([]),
396
+ )
397
+
398
+
399
+ def test_migrate_apply_runs_pending(one_profile, tmp_path):
400
+ mig_dir = tmp_path / "migrations"
401
+ _write_migrations(mig_dir, {
402
+ "001_init.sql": "CREATE TABLE dbo.A (id int);\nGO\nINSERT INTO dbo.A VALUES (1);\n",
403
+ })
404
+ conn = MigrateConn([])
405
+ result = main.dispatch(
406
+ "migrate",
407
+ ["--profile", "default", "--dir", str(mig_dir), "--mode", "apply", "--apply"],
408
+ conn_factory=lambda _p: conn,
409
+ )
410
+ assert result["applied_now"] == 1
411
+ assert result["results"][0]["status"] == "applied"
412
+ assert result["results"][0]["batches"] == 2 # GO split into 2 batches
413
+ # a tracking INSERT was issued
414
+ assert any("INSERT INTO" in sql and "__schema_migrations" in sql
415
+ for sql, _ in conn.executed)
416
+
417
+
418
+ def test_migrate_apply_dry_run_does_not_record(one_profile, tmp_path):
419
+ mig_dir = tmp_path / "migrations"
420
+ _write_migrations(mig_dir, {"001_init.sql": "SELECT 1;\n"})
421
+ conn = MigrateConn([])
422
+ result = main.dispatch(
423
+ "migrate",
424
+ ["--profile", "default", "--dir", str(mig_dir),
425
+ "--mode", "apply", "--apply", "--dry-run"],
426
+ conn_factory=lambda _p: conn,
427
+ )
428
+ assert result["dry_run"] is True
429
+ assert result["results"][0]["status"] == "dry-run-ok"
430
+ # no tracking INSERT in dry-run
431
+ assert not any("INSERT INTO" in sql and "__schema_migrations" in sql
432
+ for sql, _ in conn.executed)
433
+ # but a ROLLBACK was issued for the file's transaction
434
+ assert any("ROLLBACK" in sql for sql, _ in conn.executed)
435
+
436
+
437
+ class BatchCursor:
438
+ """Fake connection + cursor for apply_migration_sql. execute() opens a batch; the
439
+ results that follow its first one are listed per marker found in the SQL, and an
440
+ Exception among them is raised when nextset() reaches it, as pyodbc does."""
441
+
442
+ def __init__(self, later_results_by_marker):
443
+ self._by_marker = later_results_by_marker
444
+ self._pending = []
445
+ self.executed = []
446
+
447
+ def cursor(self):
448
+ return self
449
+
450
+ def execute(self, sql, *params):
451
+ self.executed.append(sql)
452
+ self._pending = list(next((r for m, r in self._by_marker.items() if m in sql), []))
453
+
454
+ def nextset(self):
455
+ if not self._pending:
456
+ return False
457
+ nxt = self._pending.pop(0)
458
+ if isinstance(nxt, Exception):
459
+ raise nxt
460
+ return True
461
+
462
+ def close(self):
463
+ pass
464
+
465
+
466
+ def test_apply_migration_sql_surfaces_an_error_after_a_row_count():
467
+ # The INSERT answers "1 row affected" first, the THROW after it. Undrained, XACT_ABORT
468
+ # rolled the file back on the server while the tool reported it applied.
469
+ conn = BatchCursor({"INSERT dbo.T": [RuntimeError("check failed (51120)")]})
470
+ with pytest.raises(RuntimeError, match="51120"):
471
+ schema.apply_migration_sql(conn, "INSERT dbo.T VALUES (1);\n;THROW 51120, 'check failed', 1;\n")
472
+ assert any("ROLLBACK" in sql for sql in conn.executed)
473
+ assert not any("COMMIT" in sql for sql in conn.executed)
474
+
475
+
476
+ def test_apply_migration_sql_commits_after_draining_a_clean_batch():
477
+ conn = BatchCursor({"INSERT dbo.T": ["1 row affected"]})
478
+ assert schema.apply_migration_sql(conn, "INSERT dbo.T VALUES (1);\nINSERT dbo.T VALUES (2);\n") == 1
479
+ assert conn.executed[-1] == "IF @@TRANCOUNT > 0 COMMIT TRANSACTION;"
480
+
481
+
482
+ def test_tracking_table_is_unicode_with_a_named_primary_key():
483
+ # Databases that hold only nvarchar must not get a varchar column from the tool itself, and a
484
+ # system-named PK (PK____schema__<hash>) differs per database and breaks a parity compare.
485
+ import re
486
+ ddl = schema._ENSURE_TABLE_SQL
487
+ assert not re.search(r"(?<![N\w])(VAR)?CHAR\s*\(", ddl, re.I)
488
+ assert "CONSTRAINT PK___schema_migrations PRIMARY KEY" in ddl
@@ -0,0 +1,123 @@
1
+ name: sqlserver
2
+ description: Read-only SQL Server queries over pyodbc with named connection profiles. SELECT-only by default (--write to override); returns rows as JSON; schema/table introspection.
3
+ version: 0.1.0
4
+ runtime: python
5
+ entrypoint: main.py
6
+
7
+ # Secrets are PER-PROFILE and dynamic, so none are declared here.
8
+ # Each profile's password lives in Windows Credential Manager under
9
+ # agents-and-tools:sqlserver:<profile-name> and is read at runtime via
10
+ # tools._lib.creds.get("sqlserver", <profile>). Set one with:
11
+ # python scripts/set-credential.py sqlserver <profile>
12
+ # Non-secret profile config (server/database/username/driver/tls) lives in
13
+ # this tool's profiles.json — never the password.
14
+ secrets: []
15
+
16
+ routing:
17
+ triggers:
18
+ - run a SQL Server query
19
+ - query a SQL Server / MSSQL database
20
+ - read a table from SQL Server
21
+ - list SQL Server tables or columns
22
+ primary_action: query
23
+ example: sqlserver query --profile default --sql "SELECT TOP 10 * FROM dbo.Customer"
24
+
25
+ actions:
26
+ - name: profiles
27
+ description: List configured connection profiles (no passwords).
28
+ args: []
29
+ output_schema: '{ "count": N, "profiles": [ {name, server, database, ..., has_password} ] }'
30
+
31
+ - name: add-profile
32
+ description: Store a connection profile (config only; set the password separately via set-credential).
33
+ args:
34
+ - {name: name, type: string, required: true, description: Profile name (also the credential name)}
35
+ - {name: server, type: string, required: true, description: "Host, host\\instance, or fqdn"}
36
+ - {name: database, type: string, description: "Default database (optional; one profile can serve many DBs - pick per call with --database)"}
37
+ - {name: username, type: string, description: SQL login (omit for a trusted/Windows connection)}
38
+ - {name: port, type: integer, description: "TCP port (appended as server,port)"}
39
+ - {name: driver, type: string, description: ODBC driver name (default = newest ODBC Driver for SQL Server installed on this machine)}
40
+ - {name: encrypt, type: string, description: Encrypt the connection - yes or no (default yes)}
41
+ - {name: trust-server-certificate, type: string, description: Trust a self-signed cert - yes or no (default no)}
42
+ - {name: connect-timeout, type: integer, description: Connect timeout seconds (default 30)}
43
+ - {name: statement-timeout, type: integer, description: "Statement timeout seconds, 0=unbounded (default 300)"}
44
+ - {name: overwrite, type: boolean, description: Replace an existing profile}
45
+ output_schema: '{ "name": "...", "server": "...", "database": "...", "has_password": false, "note": "..." }'
46
+
47
+ - name: test-connection
48
+ description: Connect and return the masked connection string + server version (never the password).
49
+ args:
50
+ - {name: profile, type: string, required: true, description: Profile name}
51
+ output_schema: '{ "profile": "...", "connection_string": "...PWD=***...", "server_version": "...", "connected": true }'
52
+
53
+ - name: query
54
+ description: Run read-only SQL (SELECT by default; --write allows non-SELECT). Params bound via ? placeholders, never interpolated.
55
+ args:
56
+ - {name: profile, type: string, required: true, description: Profile name}
57
+ - {name: sql, type: string, required: true, description: SQL statement}
58
+ - {name: params, type: string, description: "Parameter values as a JSON array, bound via ? placeholders"}
59
+ - {name: max-rows, type: integer, description: Cap rows returned (default 1000; 0=unbounded)}
60
+ - {name: write, type: boolean, description: Allow a non-SELECT/DDL/multi statement (off by default)}
61
+ - {name: database, type: string, description: Run against this database instead of the profile's}
62
+ - {name: no-normalize-eol, type: boolean, description: "Keep SQL line endings as-is (default: normalize to CRLF so CREATE/ALTER object definitions store consistent EOLs and SSMS does not flag inconsistent line endings)"}
63
+ output_schema: '{ "columns": [...], "rows": [ {...} ], "row_count": N, "truncated": false, "write": false, "eol_normalized": true }'
64
+
65
+ - name: tables
66
+ description: List tables and views, optionally restricted to one schema.
67
+ args:
68
+ - {name: profile, type: string, required: true, description: Profile name}
69
+ - {name: database, type: string, description: List tables from this database instead of the profile's}
70
+ - {name: schema, type: string, description: Restrict to one schema}
71
+ output_schema: '{ "profile": "...", "count": N, "tables": [ {TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE} ] }'
72
+
73
+ - name: columns
74
+ description: List a table's columns (name, type, nullable, length, default).
75
+ args:
76
+ - {name: profile, type: string, required: true, description: Profile name}
77
+ - {name: database, type: string, description: Read columns from this database instead of the profile's}
78
+ - {name: table, type: string, required: true, description: Table name (schema.table or table)}
79
+ output_schema: '{ "profile": "...", "table": "...", "count": N, "columns": [ {COLUMN_NAME, DATA_TYPE, IS_NULLABLE, ...} ] }'
80
+
81
+ - name: schema-extract
82
+ description: Mirror all DB objects to local .sql files (one per object; incremental; read-only).
83
+ args:
84
+ - {name: profile, type: string, required: true, description: Profile name}
85
+ - {name: database, type: string, description: Extract this database instead of the profile's}
86
+ - {name: out, type: string, description: "Mirror output directory (default ./db-mirror/<profile>)"}
87
+ - {name: types, type: string, description: "Comma-separated type letters to extract (P,FN,TF,IF,V,TR,U); default all"}
88
+ - {name: full, type: boolean, description: Wipe the mirror and re-extract everything}
89
+ - {name: dry-run, type: boolean, description: Report what would change without writing}
90
+ output_schema: '{ "profile": "...", "database": "...", "out": "...", "written": N, "unchanged": N, "removed": N, "total": N, "by_type": {}, "dry_run": false }'
91
+
92
+ - name: schema-diff
93
+ description: Diff two schema mirrors or live profiles (objects added/removed/changed + unified diffs). Read-only.
94
+ args:
95
+ - {name: left, type: string, required: true, description: "Mirror directory OR profile:NAME for the left side"}
96
+ - {name: right, type: string, required: true, description: "Mirror directory OR profile:NAME for the right side"}
97
+ - {name: database-left, type: string, description: Database override when --left is a profile}
98
+ - {name: database-right, type: string, description: Database override when --right is a profile}
99
+ - {name: types, type: string, description: "Comma-separated type letters to extract for profile sides (P,FN,TF,IF,V,TR,U); default all"}
100
+ - {name: no-diff-text, type: boolean, description: Only list added/removed/changed names (omit unified diffs)}
101
+ output_schema: '{ "added": [...], "removed": [...], "changed": [ {relpath, diff} ], "unchanged": N, "identical": false, "summary": {added, removed, changed} }'
102
+
103
+ - name: migrate
104
+ description: List or apply versioned .sql migrations (forward-only; tracking table; apply gated behind --apply). list is read-only and the default.
105
+ args:
106
+ - {name: profile, type: string, required: true, description: Profile name}
107
+ - {name: database, type: string, description: Migrate this database instead of the profile's}
108
+ - {name: dir, type: string, description: "Migrations directory (default ./db-migrations/<profile>)"}
109
+ - {name: mode, type: string, description: "list (read-only; default) or apply (writes)"}
110
+ - {name: dry-run, type: boolean, description: Apply each pending file in a rolled-back transaction (no persist)}
111
+ - {name: apply, type: boolean, description: "Required confirmation for --mode apply (this writes)"}
112
+ - {name: accept-drift, type: boolean, description: Proceed with apply even if applied files drifted on disk}
113
+ output_schema: '{ "profile": "...", "mode": "list", "applied": [...], "pending": [ {migration_id, filename, danger_warnings} ], "drift": [...], "results": [...] }'
114
+
115
+ requires:
116
+ - name: odbc-sqlserver
117
+ kind: driver
118
+ why: >
119
+ pyodbc ships in the venv but the Microsoft ODBC driver does not; without it
120
+ every DB action fails with missing_dependency while the tool still loads.
121
+ check: >-
122
+ {python} -c "import pyodbc,sys; sys.exit(0 if [d for d in pyodbc.drivers() if 'SQL Server' in d] else 1)"
123
+ install: winget install --id Microsoft.msodbcsql.18 -e --silent