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,187 @@
1
+ """Engine-agnostic layout verification: measure the readability of a laid-out flow.
2
+
3
+ Works on ANY flow's stored positions — whichever engine (legacy `engine` or `elk_engine`)
4
+ produced them — because it reads the OUTPUT geometry, not the algorithm. Pure + offline
5
+ (no network, no rendering).
6
+
7
+ `build_report(obj, flow_id)` returns:
8
+ { ok, hard_issues, metrics, containers } where
9
+ - hard_issues = overlaps + container children rendered outside their frame (real defects)
10
+ - metrics = crossings, edge lengths, back-edges, bbox/aspect, vertical rows, fill
11
+ - containers = per For-Each: frame size, inner padding L/T/R/B, inner spacing, warnings
12
+ """
13
+ from __future__ import annotations
14
+
15
+ # readability thresholds (px) — a long edge and a min sane For-Each frame
16
+ LONG_EDGE_PX = 600
17
+ MIN_FOREACH_W = 320
18
+ MIN_FOREACH_H = 200
19
+
20
+
21
+ def _g(d, *ks, default=None):
22
+ if not isinstance(d, dict):
23
+ return default
24
+ low = {str(k).lower(): v for k, v in d.items()}
25
+ for k in ks:
26
+ if k.lower() in low:
27
+ return low[k.lower()]
28
+ return default
29
+
30
+
31
+ def _select_flow(obj: dict, flow_id: str | None) -> dict:
32
+ flows = _g(obj, "Flows", "flows")
33
+ if flows is None:
34
+ return obj
35
+ if flow_id:
36
+ f = next((x for x in flows if _g(x, "Id", "id") == flow_id), None)
37
+ if f is None:
38
+ raise ValueError(f"flow_id {flow_id} not found")
39
+ return f
40
+ if len(flows) == 1:
41
+ return flows[0]
42
+ raise ValueError(f"bundle has {len(flows)} flows; pass flow_id")
43
+
44
+
45
+ def _extract(flow: dict) -> dict:
46
+ """Absolute geometry: node centres, edge attach-points (area = frame top-left), edges."""
47
+ acts = _g(flow, "actions", "Actions", default=[]) or []
48
+ nodes = {}
49
+ for a in acts:
50
+ cd = _g(a, "customData", "CustomData", default={}) or {}
51
+ pos = _g(cd, "position", default={}) or {}
52
+ asz = _g(cd, "areaSize", default={}) or {}
53
+ is_area = _g(cd, "type") == "area"
54
+ nodes[_g(a, "id", "Id")] = {
55
+ "x": float(_g(pos, "x", default=0) or 0), "y": float(_g(pos, "y", default=0) or 0),
56
+ "parent": _g(a, "parentId", "ParentId"), "is_area": is_area,
57
+ "w": float(_g(asz, "width", default=48) or 48) if is_area else 48.0,
58
+ "h": float(_g(asz, "height", default=48) or 48) if is_area else 48.0,
59
+ "name": _g(cd, "name") or _g(a, "actionTemplateName", "ActionTemplateName") or _g(a, "id", "Id"),
60
+ }
61
+ cen, att = {}, {}
62
+ for aid, n in nodes.items():
63
+ par = n["parent"]
64
+ if n["is_area"]:
65
+ base_x = n["x"] if par not in nodes else nodes[par]["x"] + n["x"]
66
+ base_y = n["y"] if par not in nodes else nodes[par]["y"] + n["y"]
67
+ cen[aid] = {"x": base_x + n["w"] / 2, "y": base_y + n["h"] / 2}
68
+ att[aid] = {"x": base_x, "y": base_y}
69
+ elif par in nodes and nodes[par]["is_area"]:
70
+ cen[aid] = {"x": nodes[par]["x"] + n["x"], "y": nodes[par]["y"] + n["y"]}
71
+ att[aid] = cen[aid]
72
+ else:
73
+ cen[aid] = {"x": n["x"], "y": n["y"]}
74
+ att[aid] = cen[aid]
75
+ edges = []
76
+ for a in acts:
77
+ s = _g(a, "id", "Id")
78
+ for p in _g(a, "ports", "Ports", default=[]) or []:
79
+ d = _g(p, "destinationId", "DestinationId")
80
+ src = _g(p, "sourceId", "SourceId") or s
81
+ t = int(_g(p, "type", "Type", default=0) or 0)
82
+ if src in nodes and d in nodes and src != d:
83
+ edges.append((src, d, t))
84
+ return {"nodes": nodes, "cen": cen, "att": att, "edges": edges}
85
+
86
+
87
+ def _seg(a, b, c, d) -> bool:
88
+ def o(p, q, r):
89
+ return (q["y"] - p["y"]) * (r["x"] - q["x"]) - (q["x"] - p["x"]) * (r["y"] - q["y"])
90
+ return (o(a, b, c) > 0) != (o(a, b, d) > 0) and (o(c, d, a) > 0) != (o(c, d, b) > 0)
91
+
92
+
93
+ def _hard_issues(geo: dict) -> list[dict]:
94
+ """Overlaps between leaf nodes + container children rendered outside their frame."""
95
+ nodes, cen = geo["nodes"], geo["cen"]
96
+ issues = []
97
+ for aid, n in nodes.items():
98
+ par = n["parent"]
99
+ if par in nodes and nodes[par]["is_area"]:
100
+ pp, fx, fy = nodes[par], nodes[par]["x"], nodes[par]["y"]
101
+ cx, cy = cen[aid]["x"], cen[aid]["y"]
102
+ if not (fx - 1 <= cx - 24 and cx + 24 <= fx + pp["w"] + 1
103
+ and fy - 1 <= cy - 24 and cy + 24 <= fy + pp["h"] + 1):
104
+ issues.append({"type": "child_outside_frame", "child": n["name"], "area": pp["name"]})
105
+ leaves = [aid for aid, n in nodes.items() if not n["is_area"]]
106
+ for i in range(len(leaves)):
107
+ a = cen[leaves[i]]
108
+ for j in range(i + 1, len(leaves)):
109
+ b = cen[leaves[j]]
110
+ if abs(a["x"] - b["x"]) < 46 and abs(a["y"] - b["y"]) < 46:
111
+ issues.append({"type": "overlap",
112
+ "a": nodes[leaves[i]]["name"], "b": nodes[leaves[j]]["name"]})
113
+ return issues
114
+
115
+
116
+ def _metrics(geo: dict) -> dict:
117
+ att, edges, nodes, cen = geo["att"], geo["edges"], geo["nodes"], geo["cen"]
118
+ cx = [c["x"] for c in cen.values()] or [0]
119
+ cy = [c["y"] for c in cen.values()] or [0]
120
+ W, H = max(cx) - min(cx) + 68, max(cy) - min(cy) + 68
121
+ E = [(att[s], att[d]) for s, d, _ in edges]
122
+ cr = 0
123
+ for i in range(len(E)):
124
+ s1, d1, _ = edges[i]
125
+ for j in range(i + 1, len(E)):
126
+ s2, d2, _ = edges[j]
127
+ if len({s1, d1, s2, d2}) < 4:
128
+ continue
129
+ if _seg(E[i][0], E[i][1], E[j][0], E[j][1]):
130
+ cr += 1
131
+ lens = [abs(att[s]["x"] - att[d]["x"]) + abs(att[s]["y"] - att[d]["y"]) for s, d, _ in edges]
132
+ back = sum(1 for s, d, _ in edges if att[d]["x"] < att[s]["x"] - 24)
133
+ rows = len({round(c["y"] / 30) for c in cen.values()})
134
+ fill = (len(nodes) * 68 * 68) / (W * H) if W * H else 0
135
+ return {
136
+ "nodes": len(nodes), "edges": len(edges), "crossings": cr, "back_edges": back,
137
+ "max_edge_px": round(max(lens)) if lens else 0,
138
+ "mean_edge_px": round(sum(lens) / len(lens)) if lens else 0,
139
+ "long_edges": sum(1 for L in lens if L > LONG_EDGE_PX),
140
+ "width": round(W), "height": round(H),
141
+ "aspect_w_to_h": round(W / H, 2) if H else 0,
142
+ "vertical_rows": rows, "fill_pct": round(fill * 100, 1),
143
+ }
144
+
145
+
146
+ def _containers(geo: dict) -> list[dict]:
147
+ nodes = geo["nodes"]
148
+ out = []
149
+ for aid, n in nodes.items():
150
+ if not n["is_area"]:
151
+ continue
152
+ kids = [k for k in nodes.values() if k["parent"] == aid]
153
+ c = {"name": n["name"], "width": round(n["w"]), "height": round(n["h"]),
154
+ "children": len(kids), "warnings": []}
155
+ if kids:
156
+ cxs = [k["x"] for k in kids]
157
+ cys = [k["y"] for k in kids]
158
+ pad = {"l": round(min(cxs) - 24), "t": round(min(cys) - 24),
159
+ "r": round(n["w"] - (max(cxs) + 24)), "b": round(n["h"] - (max(cys) + 24))}
160
+ c["padding"] = pad
161
+ xs = sorted(cxs)
162
+ c["inner_h_spacing"] = [round(xs[i + 1] - xs[i]) for i in range(len(xs) - 1)]
163
+ for side, v in pad.items():
164
+ if v < 0:
165
+ c["warnings"].append(f"negative {side} padding ({v}) — child overflows frame")
166
+ if n["w"] < MIN_FOREACH_W:
167
+ c["warnings"].append(f"width {round(n['w'])} < min {MIN_FOREACH_W}")
168
+ if n["h"] < MIN_FOREACH_H:
169
+ c["warnings"].append(f"height {round(n['h'])} < min {MIN_FOREACH_H}")
170
+ out.append(c)
171
+ return out
172
+
173
+
174
+ def build_report(obj: dict, flow_id: str | None = None) -> dict:
175
+ flow = _select_flow(obj, flow_id)
176
+ geo = _extract(flow)
177
+ hard = _hard_issues(geo)
178
+ containers = _containers(geo)
179
+ container_warnings = [w for c in containers for w in c["warnings"]]
180
+ return {
181
+ "ok": not hard and not container_warnings,
182
+ "flow_id": _g(flow, "Id", "id"),
183
+ "hard_issue_count": len(hard),
184
+ "hard_issues": hard[:40],
185
+ "metrics": _metrics(geo),
186
+ "containers": containers,
187
+ }
@@ -0,0 +1,179 @@
1
+ """procesio tool entrypoint - action dispatch over the PROCESIO Web API.
2
+
3
+ Dual auth (API key OR username/password -> Bearer) with a multi-credential
4
+ profile store; a generic `request` action covering every documented endpoint;
5
+ curated read/run actions for the common surface.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ TOOL_ROOT = Path(__file__).resolve().parent
13
+ FRAMEWORK_ROOT = TOOL_ROOT.parents[1]
14
+ # .venv layout is per-OS: Scripts/python.exe on Windows, bin/python everywhere else.
15
+ _VENV_PY = (FRAMEWORK_ROOT / ".venv" / "Scripts" / "python.exe" if sys.platform == "win32"
16
+ else FRAMEWORK_ROOT / ".venv" / "bin" / "python")
17
+ if _VENV_PY.exists() and Path(sys.executable).resolve() != _VENV_PY.resolve():
18
+ import subprocess
19
+ sys.exit(subprocess.run([str(_VENV_PY), __file__, *sys.argv[1:]]).returncode)
20
+
21
+ import argparse # noqa: E402
22
+
23
+ if str(FRAMEWORK_ROOT) not in sys.path:
24
+ sys.path.insert(0, str(FRAMEWORK_ROOT))
25
+
26
+ from tools._lib.io import emit, fail # noqa: E402
27
+ from tools.procesio import errors # noqa: E402
28
+ from tools.procesio.actiondef import ActionDef # noqa: E402
29
+ from tools.procesio.client import ProcesioClient # noqa: E402
30
+
31
+
32
+ class _Parser(argparse.ArgumentParser):
33
+ def error(self, message: str):
34
+ raise errors.UsageError(message)
35
+
36
+
37
+ # Known footguns on raw/autogenerated endpoints: the call SUCCEEDS but leaves the
38
+ # workspace in a state the caller rarely intends. Attached to the emitted JSON as
39
+ # `warning` so it is visible without changing the action's contract. One line per
40
+ # action; keep the text actionable.
41
+ ADVISORIES = {
42
+ "post-projects-by-id-instances-publish": (
43
+ "publish CREATES an instance in status 1 ('starting') with 0 action runs and "
44
+ "does NOT run it — publish and launch are a pair (run-process does both). A "
45
+ "WEBHOOK-triggered process needs no publish at all: the webhook launch "
46
+ "publishes+launches itself. Calling publish 'to activate' just accumulates "
47
+ "instances stuck at 'starting' (they cannot be stopped via the API — only in "
48
+ "the UI). Launch it with post-projects-instances-by-id-launch, or use "
49
+ "run-process, or simply don't publish."
50
+ ),
51
+ }
52
+
53
+
54
+ def _advise(action: str, result):
55
+ """Attach a known-footgun advisory to a successful result (non-destructive)."""
56
+ note = ADVISORIES.get(action)
57
+ if note and isinstance(result, dict):
58
+ result.setdefault("warning", note)
59
+ return result
60
+
61
+
62
+ def collect_actions() -> dict[str, ActionDef]:
63
+ from tools.procesio import autogen
64
+ from tools.procesio.handlers import (
65
+ auth_actions, catalog, customaction_ops, datastore_ops, datatype_ops,
66
+ dto_actions, environment_admin, files,
67
+ flowgraph, form_chains, form_code, form_element, form_events, form_update, formprocess, generic,
68
+ layout, usageguide,
69
+ process_layout, process_naming, processes, profile_admin,
70
+ flowlint, fevalidate, nodeparams, resource_ops, schedules, sqlactions, transport,
71
+ )
72
+ # Curated / management actions: ergonomic, hand-written, well-tested.
73
+ curated: dict[str, ActionDef] = {}
74
+ curated.update(profile_admin.ACTIONS)
75
+ # Environment registry: list/add/set/remove/show PROCESIO environments (URLs).
76
+ curated.update(environment_admin.ACTIONS)
77
+ curated.update(auth_actions.ACTIONS)
78
+ curated.update(generic.ACTIONS)
79
+ curated.update(processes.ACTIONS)
80
+ # Submit a form the way a browser does (proves the form's own maps carry values).
81
+ curated.update(formprocess.ACTIONS)
82
+ curated.update(catalog.ACTIONS)
83
+ curated.update(transport.ACTIONS)
84
+ curated.update(schedules.ACTIONS)
85
+ # Data Store: user-defined dynamic tables — metadata + row CRUD + CSV jobs.
86
+ curated.update(datastore_ops.ACTIONS)
87
+ # DTO sub-tools: <component>-create / <component>-edit (deterministic builders).
88
+ curated.update(dto_actions.ACTIONS)
89
+ # Full data-model lifecycle: attribute add/edit/delete, get/delete, changeToPublic, clone.
90
+ curated.update(datatype_ops.ACTIONS)
91
+ # File ops: download a flow-instance file (Generate-Document output etc.).
92
+ curated.update(files.ACTIONS)
93
+ # Custom-action (connector) lifecycle: upload .nupkg / delete / list.
94
+ curated.update(customaction_ops.ACTIONS)
95
+ # Offline structural reader: parse a flow/export into a node/edge graph model.
96
+ curated.update(flowgraph.ACTIONS)
97
+ curated.update(usageguide.ACTIONS)
98
+ # Offline deterministic canvas auto-layout (re-lay-out a flow; resource map).
99
+ curated.update(layout.ACTIONS)
100
+ # Live process ops that pair with layout: duplicate a process; re-lay-out in place.
101
+ curated.update(process_layout.ACTIONS)
102
+ # Bulk-rename a live process's canvas actions (default "Node"/"Call API" labels).
103
+ curated.update(process_naming.ACTIONS)
104
+ # CRUD-parity + verification oracles: get/delete/list, validate, credential/action test, import.
105
+ curated.update(resource_ops.ACTIONS)
106
+ # In-place read/write of a form's global CSS + JS (Data.code), without the
107
+ # desired-state rebuild form-edit performs.
108
+ curated.update(form_code.ACTIONS)
109
+ # Same surgical shape, for one element's event handlers (RUN_PROCESS wiring).
110
+ curated.update(form_events.ACTIONS)
111
+ # Whole ordered chains (JS / MAP / process) of several elements in one save; MAP blocks and
112
+ # their conditions are built from names, existing events are kept by id.
113
+ curated.update(form_chains.ACTIONS)
114
+ # Same surgical shape again, for one element's PLAIN configs — label/required/
115
+ # regex/visible. Content and per-field rules belong in the DTO, not in the
116
+ # form-level JS layer where the designer cannot see them.
117
+ curated.update(form_element.ACTIONS)
118
+ # Arbitrary safe save: GET a live form, deep-merge a Data patch (and/or override
119
+ # name/status/state), PUT the accepted DTO — the general form-save form-edit isn't.
120
+ curated.update(form_update.ACTIONS)
121
+ # SQL Server action hardening: scan + convert inline <%N%> SQL to parameterized (@param) binding.
122
+ curated.update(sqlactions.ACTIONS)
123
+ # Surgical single-parameter edits on a live designer-built flow (endpoint/timeout/SQL/script):
124
+ # read the parameter surface, patch one literal, regenerate the designer layer, validate, PUT.
125
+ curated.update(nodeparams.ACTIONS)
126
+ curated.update(flowlint.ACTIONS)
127
+ # Front-end (designer-layer) validation: process-fe-validate + the pre-save gate that
128
+ # auto-runs (FE then BE) before every process-create / process-edit.
129
+ curated.update(fevalidate.ACTIONS)
130
+ # Generated actions: full 1:1 coverage of every Web-API endpoint. Curated
131
+ # names win on the (non-colliding) name space.
132
+ actions = autogen.build_actions(reserved=set(curated))
133
+ actions.update(curated)
134
+ return actions
135
+
136
+
137
+ ACTIONS = collect_actions()
138
+
139
+
140
+ def dispatch(action: str, argv: list[str], *, client_builder=None) -> dict:
141
+ if action not in ACTIONS:
142
+ raise errors.UsageError(
143
+ f"unknown action: {action}. Known: {', '.join(sorted(ACTIONS))}"
144
+ )
145
+ defn = ACTIONS[action]
146
+ parser = _Parser(prog=f"procesio {action}", description=defn.description)
147
+ defn.add_args(parser)
148
+ parsed = parser.parse_args(argv)
149
+ if defn.needs_client:
150
+ profile = getattr(parsed, "profile", None)
151
+ environment = getattr(parsed, "environment", None)
152
+ builder = client_builder or (
153
+ lambda prof: ProcesioClient(prof, environment=environment))
154
+ client = builder(profile)
155
+ wsid = getattr(parsed, "workspace_id", None)
156
+ if wsid:
157
+ client.workspace_id = wsid # per-call active-workspace override
158
+ return defn.func(client, parsed)
159
+ return defn.func(parsed)
160
+
161
+
162
+ def main(argv=None) -> None:
163
+ argv = list(sys.argv[1:] if argv is None else argv)
164
+ if not argv or argv[0] in ("-h", "--help"):
165
+ print("Actions:", file=sys.stderr)
166
+ for name in sorted(ACTIONS):
167
+ print(f" {name:<22} {ACTIONS[name].description}", file=sys.stderr)
168
+ sys.exit(0)
169
+ action, rest = argv[0], argv[1:]
170
+ try:
171
+ result = dispatch(action, rest)
172
+ except Exception as exc: # noqa: BLE001
173
+ code, message, details, exit_code = errors.classify(exc)
174
+ fail(code, message, details, exit_code)
175
+ emit(_advise(action, result))
176
+
177
+
178
+ if __name__ == "__main__":
179
+ main()
@@ -0,0 +1,193 @@
1
+ """Multi-credential profile store for PROCESIO.
2
+
3
+ The user explicitly wants "a system that allows multiple credentials so that I
4
+ can have multiple accounts, multiple api keys, etc." A *profile* is one named
5
+ credential: either an API key (workspace-scoped) or a username/password account
6
+ (full UI access). All profiles live in the OS credential store via
7
+ tools._lib.creds - NEVER on disk.
8
+
9
+ Credential-store layout (all under target agents-and-tools:procesio:<secret>):
10
+ credentials -> JSON index: [{"name","type","workspace"}, ...] (NO secrets)
11
+ default-profile -> the name used when --profile is omitted
12
+ cred-<name> -> JSON blob for one profile (CONTAINS secret values)
13
+ token-<name> -> JSON cached Bearer token for a userpass profile
14
+
15
+ A profile blob:
16
+ apikey: {"type":"apikey","key":..,"value":..,"workspace_id":<guid?>,
17
+ "workspace":<label?>,"web_base":<override?>,"auth_base":<override?>}
18
+ userpass: {"type":"userpass","username":..,"password":..,"realm":<override?>,
19
+ "client_id":<override?>,"web_base":<override?>,"auth_base":<override?>}
20
+
21
+ The index lets `list-credentials` enumerate profiles WITHOUT reading any secret
22
+ (keyring can't list keys, so the index is the source of truth for membership).
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import json
27
+
28
+ from tools._lib import creds
29
+ from tools.procesio.errors import AuthError, UsageError
30
+
31
+ TOOL = "procesio"
32
+ INDEX_SECRET = "credentials"
33
+ DEFAULT_SECRET = "default-profile"
34
+
35
+ # Fields that must never appear in a non-secret view (list-credentials, logs).
36
+ _SECRET_FIELDS = {"key", "value", "password"}
37
+
38
+
39
+ # -- index ------------------------------------------------------------------
40
+
41
+ def _load_index() -> list[dict]:
42
+ raw = creds.get_optional(TOOL, INDEX_SECRET)
43
+ if not raw:
44
+ return []
45
+ try:
46
+ data = json.loads(raw)
47
+ return data if isinstance(data, list) else []
48
+ except json.JSONDecodeError:
49
+ return []
50
+
51
+
52
+ def _save_index(index: list[dict]) -> None:
53
+ creds.set_secret(TOOL, INDEX_SECRET, json.dumps(index, ensure_ascii=False))
54
+
55
+
56
+ def _index_meta(blob: dict, name: str) -> dict:
57
+ meta = {"name": name, "type": blob.get("type")}
58
+ if blob.get("workspace"):
59
+ meta["workspace"] = blob["workspace"]
60
+ return meta
61
+
62
+
63
+ # -- profile CRUD -----------------------------------------------------------
64
+
65
+ def profile_names() -> list[str]:
66
+ return [e["name"] for e in _load_index() if e.get("name")]
67
+
68
+
69
+ def get_profile(name: str) -> dict:
70
+ raw = creds.get_optional(TOOL, f"cred-{name}")
71
+ if not raw:
72
+ raise AuthError(
73
+ f"no PROCESIO credential profile named '{name}'. "
74
+ f"Known: {', '.join(profile_names()) or '(none)'}. "
75
+ f"Add one with: run-tool procesio add-credential ..."
76
+ )
77
+ try:
78
+ blob = json.loads(raw)
79
+ except json.JSONDecodeError as e:
80
+ raise AuthError(f"profile '{name}' is corrupted: {e}") from e
81
+ if not isinstance(blob, dict) or "type" not in blob:
82
+ raise AuthError(f"profile '{name}' is malformed (no type)")
83
+ return blob
84
+
85
+
86
+ def save_profile(name: str, blob: dict) -> None:
87
+ if blob.get("type") not in ("apikey", "userpass"):
88
+ raise UsageError("profile type must be 'apikey' or 'userpass'")
89
+ creds.set_secret(TOOL, f"cred-{name}", json.dumps(blob, ensure_ascii=False))
90
+ index = [e for e in _load_index() if e.get("name") != name]
91
+ index.append(_index_meta(blob, name))
92
+ index.sort(key=lambda e: e["name"])
93
+ _save_index(index)
94
+ if not get_default():
95
+ set_default(name)
96
+
97
+
98
+ def remove_profile(name: str) -> None:
99
+ if name not in profile_names():
100
+ raise UsageError(f"no profile named '{name}'")
101
+ creds.delete(TOOL, f"cred-{name}")
102
+ creds.delete(TOOL, f"token-{name}")
103
+ creds.delete(TOOL, f"refresh-{name}")
104
+ _save_index([e for e in _load_index() if e.get("name") != name])
105
+ if get_default() == name:
106
+ remaining = profile_names()
107
+ if remaining:
108
+ set_default(remaining[0])
109
+ else:
110
+ creds.delete(TOOL, DEFAULT_SECRET)
111
+
112
+
113
+ def public_view(blob: dict, name: str) -> dict:
114
+ """A profile dict safe to return/log: secret fields removed, presence noted."""
115
+ out = {"name": name}
116
+ for k, v in blob.items():
117
+ if k in _SECRET_FIELDS:
118
+ out[f"has_{k}"] = bool(v)
119
+ else:
120
+ out[k] = v
121
+ out["has_cached_token"] = creds.has_for_report(TOOL, f"token-{name}")
122
+ return out
123
+
124
+
125
+ # -- default ----------------------------------------------------------------
126
+
127
+ def get_default() -> str | None:
128
+ return creds.get_optional(TOOL, DEFAULT_SECRET)
129
+
130
+
131
+ def set_default(name: str) -> None:
132
+ if name not in profile_names():
133
+ raise UsageError(f"cannot default to unknown profile '{name}'")
134
+ creds.set_secret(TOOL, DEFAULT_SECRET, name)
135
+
136
+
137
+ def resolve(name: str | None) -> tuple[str, dict]:
138
+ """Return (name, blob) for an explicit name, else the default, else - if
139
+ exactly one profile exists - that one. Raises a clear UsageError otherwise."""
140
+ if name:
141
+ return name, get_profile(name)
142
+ default = get_default()
143
+ if default:
144
+ return default, get_profile(default)
145
+ names = profile_names()
146
+ if len(names) == 1:
147
+ return names[0], get_profile(names[0])
148
+ raise UsageError(
149
+ "no --profile given and no default set. "
150
+ f"Profiles: {', '.join(names) or '(none)'}. "
151
+ "Set one with: run-tool procesio set-default --name <name>"
152
+ )
153
+
154
+
155
+ # -- token cache (userpass) -------------------------------------------------
156
+
157
+ def get_token_cache(name: str) -> dict | None:
158
+ raw = creds.get_optional(TOOL, f"token-{name}")
159
+ if not raw:
160
+ return None
161
+ try:
162
+ return json.loads(raw)
163
+ except json.JSONDecodeError:
164
+ return None
165
+
166
+
167
+ def set_token_cache(name: str, token: dict) -> None:
168
+ creds.set_secret(TOOL, f"token-{name}", json.dumps(token, ensure_ascii=False))
169
+
170
+
171
+ def clear_token_cache(name: str) -> None:
172
+ creds.delete(TOOL, f"token-{name}")
173
+ clear_refresh_cookie(name)
174
+
175
+
176
+ # The refresh cookie lives in its OWN entry, not alongside the access cookie.
177
+ # Windows Credential Manager caps a blob at 2560 BYTES (the tightest of the OS
178
+ # stores, so it sets the budget everywhere), and keyring stores the
179
+ # value as UTF-16LE — so the real ceiling is ~1280 CHARACTERS (measured on this
180
+ # machine). The two JWT cookies total ~1700 chars and blow past it together;
181
+ # each one alone (~961 and ~733) fits comfortably. Splitting them is what lets a
182
+ # session be renewed without re-sending the password.
183
+
184
+ def get_refresh_cookie(name: str) -> str | None:
185
+ return creds.get_optional(TOOL, f"refresh-{name}") or None
186
+
187
+
188
+ def set_refresh_cookie(name: str, value: str) -> None:
189
+ creds.set_secret(TOOL, f"refresh-{name}", value)
190
+
191
+
192
+ def clear_refresh_cookie(name: str) -> None:
193
+ creds.delete(TOOL, f"refresh-{name}")