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,578 @@
1
+ """Pluggable credential backends, selected by the ``AAT_CREDS_BACKEND`` env var.
2
+
3
+ The framework's canonical secret identity is ``agents-and-tools:<tool>:<secret>``.
4
+ Every backend resolves the same ``(tool, secret)`` pair; only WHERE it reads from
5
+ changes. With ``AAT_CREDS_BACKEND`` unset the OS-native store is chosen for the
6
+ platform (see ``default_backend_name``), so no user on any of the three desktops has
7
+ to configure anything, and a Windows session behaves exactly as it always did.
8
+
9
+ windows - Windows Credential Manager via keyring (default on win32)
10
+ macos - macOS login Keychain via keyring (default on darwin)
11
+ linux - GNOME Keyring / KWallet over D-Bus via keyring (default elsewhere)
12
+ encrypted-file - one passphrase-encrypted file (``AAT_SECRETS_FILE``); the store
13
+ for a HEADLESS machine, where no OS keyring exists
14
+ env - a single JSON blob in ``AAT_SECRETS_JSON`` = {tool:{secret:val}}
15
+ file - a directory (``AAT_SECRETS_DIR``) of ``<tool>__<secret>`` files
16
+ and/or a ``secrets.json`` (k8s Secret / mounted-file friendly)
17
+ bridge - HTTP GET to a loopback host service wrapping the host's Cred Mgr
18
+ (a container on the laptop reads host secrets; nothing copied)
19
+ procesio - HTTP GET to a PROCESIO credential resolver, scoped to the active
20
+ (workspace, user); the multi-tenant platform backend (spec P0.0-08)
21
+
22
+ The four OWNED stores (windows / macos / linux / encrypted-file) are read/write, so
23
+ ``set-credential.py`` works on every OS. The four BORROWED ones (env / file / bridge /
24
+ procesio) are READ-ONLY: those secrets are managed by a host or cluster and must never
25
+ be written from inside a container.
26
+
27
+ Every OS backend imports ``keyring`` lazily, inside the selected backend only, so this
28
+ module imports cleanly on a platform whose keyring backend is unavailable - which is
29
+ what lets a Linux container import the framework without a session bus.
30
+ """
31
+ from __future__ import annotations
32
+
33
+ import json
34
+ import os
35
+ import re
36
+ import sys
37
+ import time
38
+ import urllib.error
39
+ import urllib.request
40
+ from pathlib import Path
41
+ from typing import Protocol
42
+
43
+
44
+ class Backend(Protocol):
45
+ def get_optional(self, tool: str, secret: str) -> str | None: ...
46
+ def set(self, tool: str, secret: str, value: str) -> None: ...
47
+ def delete(self, tool: str, secret: str) -> None: ...
48
+
49
+
50
+ class _ReadOnly:
51
+ """Mixin: writes raise, so a container never pretends to own the secret store."""
52
+
53
+ name = "read-only"
54
+
55
+ def set(self, tool: str, secret: str, value: str) -> None:
56
+ raise RuntimeError(
57
+ f"credential backend {self.name!r} is read-only; manage secrets on the "
58
+ f"host/cluster, not from here")
59
+
60
+ def delete(self, tool: str, secret: str) -> None:
61
+ raise RuntimeError(
62
+ f"credential backend {self.name!r} is read-only; manage secrets on the "
63
+ f"host/cluster, not from here")
64
+
65
+
66
+ class WindowsBackend:
67
+ """Windows Credential Manager via keyring. Service = agents-and-tools:<tool>."""
68
+
69
+ name = "windows"
70
+ NAMESPACE = "agents-and-tools"
71
+
72
+ def __init__(self) -> None:
73
+ import keyring # lazy: only when this backend is selected
74
+ backend = keyring.get_keyring()
75
+ tname = type(backend).__name__
76
+ if "WinVault" not in tname and "Windows" not in tname:
77
+ try:
78
+ from keyring.backends.Windows import WinVaultKeyring
79
+ keyring.set_keyring(WinVaultKeyring())
80
+ except Exception as e: # noqa: BLE001
81
+ raise RuntimeError(
82
+ f"keyring backend is {tname}, not Windows Credential Manager. "
83
+ f"The 'windows' creds backend requires Windows. ({e})") from e
84
+ self._kr = keyring
85
+
86
+ def _svc(self, tool: str) -> str:
87
+ return f"{self.NAMESPACE}:{tool}"
88
+
89
+ def get_optional(self, tool: str, secret: str) -> str | None:
90
+ return self._kr.get_password(self._svc(tool), secret)
91
+
92
+ def set(self, tool: str, secret: str, value: str) -> None:
93
+ self._kr.set_password(self._svc(tool), secret, value)
94
+
95
+ def delete(self, tool: str, secret: str) -> None:
96
+ try:
97
+ self._kr.delete_password(self._svc(tool), secret)
98
+ except self._kr.errors.PasswordDeleteError:
99
+ pass
100
+
101
+
102
+ class MacKeychainBackend:
103
+ """macOS login Keychain via keyring. Service = agents-and-tools:<tool>.
104
+
105
+ The macOS peer of WindowsBackend: same NAMESPACE and (tool, secret) identity, so a
106
+ Mac user's secrets live in the login Keychain exactly where a Windows user's live in
107
+ Credential Manager. Read/write (set-credential.py works). keyring's macOS backend is
108
+ imported lazily so this module still imports cleanly off-Mac."""
109
+
110
+ name = "macos"
111
+ NAMESPACE = "agents-and-tools"
112
+
113
+ def __init__(self) -> None:
114
+ # Use a DIRECT macOS backend instance. Do NOT call keyring.get_keyring()
115
+ # / set_keyring(): those trigger keyring's backend auto-detection, which
116
+ # evaluates the built-in Windows backend's `priority` classproperty — and
117
+ # that raises "Requires Windows and pywin32" on macOS. Talking to the
118
+ # macOS.Keyring instance directly sidesteps auto-detection entirely.
119
+ try:
120
+ from keyring.backends import macOS as _macos
121
+ from keyring import errors as _errors
122
+ except Exception as e: # noqa: BLE001
123
+ raise RuntimeError(
124
+ f"macOS Keychain keyring backend unavailable ({e}); "
125
+ f"the 'macos' creds backend requires macOS.") from e
126
+ self._kc = _macos.Keyring()
127
+ self._errors = _errors
128
+
129
+ def _svc(self, tool: str) -> str:
130
+ return f"{self.NAMESPACE}:{tool}"
131
+
132
+ def get_optional(self, tool: str, secret: str) -> str | None:
133
+ return self._kc.get_password(self._svc(tool), secret)
134
+
135
+ def set(self, tool: str, secret: str, value: str) -> None:
136
+ self._kc.set_password(self._svc(tool), secret, value)
137
+
138
+ def delete(self, tool: str, secret: str) -> None:
139
+ try:
140
+ self._kc.delete_password(self._svc(tool), secret)
141
+ except self._errors.PasswordDeleteError:
142
+ pass
143
+
144
+
145
+ class LinuxSecretServiceBackend:
146
+ """Linux desktop secret store via keyring. Service = agents-and-tools:<tool>.
147
+
148
+ The Linux peer of WindowsBackend / MacKeychainBackend: same NAMESPACE and
149
+ ``(tool, secret)`` identity, so a Linux user's secrets live in GNOME Keyring or
150
+ KWallet exactly where a Windows user's live in Credential Manager. Read/write, so
151
+ ``set-credential.py`` works.
152
+
153
+ Like the macOS backend, this talks to a DIRECT backend instance and never calls
154
+ ``keyring.get_keyring()`` / ``set_keyring()``: auto-detection evaluates the built-in
155
+ Windows backend's ``priority`` classproperty, which raises off-Windows.
156
+
157
+ Availability is probed through each backend's ``priority`` classproperty, which is
158
+ keyring's own "can I run here" contract - it raises when the D-Bus Secret Service
159
+ (or KWallet) is not reachable. That is the normal case on a HEADLESS server: there
160
+ is no session bus, so no OS keyring exists to talk to. The error then names the
161
+ backends that do work without a desktop session rather than leaving the caller with
162
+ a D-Bus traceback."""
163
+
164
+ name = "linux"
165
+ NAMESPACE = "agents-and-tools"
166
+
167
+ # (module path, class name) in preference order. SecretService covers GNOME /
168
+ # freedesktop.org (the default on most distros); kwallet covers KDE.
169
+ _CANDIDATES = (
170
+ ("keyring.backends.SecretService", "Keyring"),
171
+ ("keyring.backends.kwallet", "DBusKeyring"),
172
+ )
173
+
174
+ def __init__(self) -> None:
175
+ try:
176
+ from keyring import errors as _errors
177
+ except Exception as e: # noqa: BLE001
178
+ raise RuntimeError(f"keyring is not installed ({e})") from e
179
+ self._errors = _errors
180
+
181
+ import importlib
182
+
183
+ attempts: list[str] = []
184
+ for mod_path, cls_name in self._CANDIDATES:
185
+ try:
186
+ cls = getattr(importlib.import_module(mod_path), cls_name)
187
+ cls.priority # noqa: B018 - keyring's own availability probe; raises when unusable
188
+ self._kr = cls()
189
+ self.backend_name = f"{mod_path}.{cls_name}"
190
+ return
191
+ except Exception as e: # noqa: BLE001 - try the next candidate
192
+ attempts.append(f"{mod_path}.{cls_name}: {e}")
193
+ raise RuntimeError(
194
+ "no Linux OS keyring is reachable (tried " + "; ".join(attempts) + "). "
195
+ "On a headless machine there is no session keyring: set "
196
+ "AAT_CREDS_BACKEND=encrypted-file (read/write, passphrase in "
197
+ "AAT_SECRETS_PASSPHRASE), or =file / =env for secrets managed by the "
198
+ "host or cluster.")
199
+
200
+ def _svc(self, tool: str) -> str:
201
+ return f"{self.NAMESPACE}:{tool}"
202
+
203
+ def get_optional(self, tool: str, secret: str) -> str | None:
204
+ return self._kr.get_password(self._svc(tool), secret)
205
+
206
+ def set(self, tool: str, secret: str, value: str) -> None:
207
+ self._kr.set_password(self._svc(tool), secret, value)
208
+
209
+ def delete(self, tool: str, secret: str) -> None:
210
+ try:
211
+ self._kr.delete_password(self._svc(tool), secret)
212
+ except self._errors.PasswordDeleteError:
213
+ pass
214
+
215
+
216
+ class EncryptedFileBackend:
217
+ """A single passphrase-encrypted file, for a machine with no OS keyring.
218
+
219
+ The headless-Linux (and container-with-state) peer of the three OS stores: same
220
+ ``(tool, secret)`` identity, READ/WRITE, so ``set-credential.py`` works where
221
+ GNOME Keyring and KWallet do not exist. Distinct from ``file`` / ``env``, which are
222
+ read-only views of secrets some host or cluster already manages.
223
+
224
+ Storage: one JSON envelope at ``AAT_SECRETS_FILE``
225
+ (default ``~/.config/agents-and-tools/secrets.enc``) holding a per-file scrypt salt
226
+ and a Fernet token over ``{tool: {secret: value}}``. The file is written 0600 and
227
+ replaced atomically, so a crash mid-write cannot leave a half-written store that
228
+ reads as an empty one.
229
+
230
+ The passphrase comes from ``AAT_SECRETS_PASSPHRASE``, or an interactive prompt ONLY
231
+ when stdin is a TTY. An agent runs with stdin closed, so prompting there would hang
232
+ forever instead of failing; the error says which variable to set."""
233
+
234
+ name = "encrypted-file"
235
+ VERSION = 1
236
+ SCRYPT_N = 2 ** 15
237
+ SCRYPT_R = 8
238
+ SCRYPT_P = 1
239
+
240
+ def __init__(self) -> None:
241
+ self._path = Path(
242
+ os.environ.get("AAT_SECRETS_FILE")
243
+ or Path.home() / ".config" / "agents-and-tools" / "secrets.enc")
244
+ self._cache: dict | None = None
245
+
246
+ # --- crypto ----------------------------------------------------------
247
+
248
+ @staticmethod
249
+ def _passphrase() -> str:
250
+ pw = os.environ.get("AAT_SECRETS_PASSPHRASE")
251
+ if pw:
252
+ return pw
253
+ if sys.stdin is not None and sys.stdin.isatty():
254
+ import getpass
255
+ pw = getpass.getpass("AAT secrets passphrase: ")
256
+ if pw:
257
+ return pw
258
+ raise RuntimeError(
259
+ "no passphrase for the encrypted-file credential store: set "
260
+ "AAT_SECRETS_PASSPHRASE (a non-interactive run cannot be prompted)")
261
+
262
+ def _fernet(self, salt: bytes):
263
+ try:
264
+ from cryptography.fernet import Fernet
265
+ from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
266
+ except Exception as e: # noqa: BLE001
267
+ raise RuntimeError(
268
+ f"the encrypted-file credential backend needs the 'cryptography' "
269
+ f"package ({e}); install it or use AAT_CREDS_BACKEND=file/env") from e
270
+ import base64
271
+ key = Scrypt(salt=salt, length=32, n=self.SCRYPT_N, r=self.SCRYPT_R,
272
+ p=self.SCRYPT_P).derive(self._passphrase().encode("utf-8"))
273
+ return Fernet(base64.urlsafe_b64encode(key))
274
+
275
+ # --- store -----------------------------------------------------------
276
+
277
+ def _load(self) -> dict:
278
+ if self._cache is not None:
279
+ return self._cache
280
+ if not self._path.exists():
281
+ self._cache = {}
282
+ return self._cache
283
+ import base64
284
+ try:
285
+ env = json.loads(self._path.read_text(encoding="utf-8"))
286
+ except ValueError as e:
287
+ raise RuntimeError(f"{self._path} is not a valid secret store: {e}") from e
288
+ if int(env.get("version", 0)) != self.VERSION:
289
+ raise RuntimeError(
290
+ f"{self._path}: unsupported store version {env.get('version')!r}")
291
+ f = self._fernet(base64.b64decode(env["salt"]))
292
+ try:
293
+ plain = f.decrypt(env["data"].encode("ascii"))
294
+ except Exception as e: # noqa: BLE001 - InvalidToken and friends
295
+ raise RuntimeError(
296
+ f"cannot decrypt {self._path}: wrong passphrase, or the file was "
297
+ f"written with a different one ({type(e).__name__})") from e
298
+ self._cache = json.loads(plain.decode("utf-8"))
299
+ return self._cache
300
+
301
+ def _save(self, data: dict) -> None:
302
+ import base64
303
+ salt = os.urandom(16) # fresh salt per write: never reuse a KDF salt
304
+ blob = self._fernet(salt).encrypt(
305
+ json.dumps(data, ensure_ascii=False).encode("utf-8"))
306
+ env = {"version": self.VERSION, "kdf": "scrypt",
307
+ "n": self.SCRYPT_N, "r": self.SCRYPT_R, "p": self.SCRYPT_P,
308
+ "salt": base64.b64encode(salt).decode("ascii"),
309
+ "data": blob.decode("ascii")}
310
+ self._path.parent.mkdir(parents=True, exist_ok=True)
311
+ tmp = self._path.with_suffix(self._path.suffix + ".tmp")
312
+ tmp.write_text(json.dumps(env), encoding="utf-8")
313
+ try:
314
+ os.chmod(tmp, 0o600) # no-op semantics on Windows; correct on POSIX
315
+ except OSError:
316
+ pass
317
+ os.replace(tmp, self._path) # atomic: a crash never leaves a partial store
318
+ self._cache = data
319
+
320
+ # --- Backend protocol -------------------------------------------------
321
+
322
+ def get_optional(self, tool: str, secret: str) -> str | None:
323
+ v = (self._load().get(tool) or {}).get(secret)
324
+ return str(v) if v is not None else None
325
+
326
+ def set(self, tool: str, secret: str, value: str) -> None:
327
+ data = dict(self._load())
328
+ data[tool] = {**(data.get(tool) or {}), secret: value}
329
+ self._save(data)
330
+
331
+ def delete(self, tool: str, secret: str) -> None:
332
+ data = dict(self._load())
333
+ bucket = dict(data.get(tool) or {})
334
+ if bucket.pop(secret, None) is None:
335
+ return
336
+ if bucket:
337
+ data[tool] = bucket
338
+ else:
339
+ data.pop(tool, None)
340
+ self._save(data)
341
+
342
+
343
+ class EnvJsonBackend(_ReadOnly):
344
+ """Secrets from one JSON blob in AAT_SECRETS_JSON = {"tool": {"secret": "val"}}.
345
+ Simplest for docker-compose (pass a single env var)."""
346
+
347
+ name = "env"
348
+
349
+ def __init__(self) -> None:
350
+ raw = (os.environ.get("AAT_SECRETS_JSON") or "").strip()
351
+ try:
352
+ self._data = json.loads(raw) if raw else {}
353
+ except ValueError as e:
354
+ raise RuntimeError(f"AAT_SECRETS_JSON is not valid JSON: {e}") from e
355
+
356
+ def get_optional(self, tool: str, secret: str) -> str | None:
357
+ v = (self._data.get(tool) or {}).get(secret)
358
+ return str(v) if v is not None else None
359
+
360
+
361
+ class FileSecretBackend(_ReadOnly):
362
+ """Secrets from a directory (AAT_SECRETS_DIR, default /run/secrets/aat) of
363
+ ``<tool>__<secret>`` files (k8s Secret mounts each key as a file) and/or a
364
+ ``secrets.json`` in the same dir.
365
+
366
+ Multi-user: when AAT_USER_ID is set, a per-user subdir ``<dir>/<user>/`` is searched
367
+ FIRST, then the shared dir — so each user's mounted Secret isolates their
368
+ credentials (spec 08). Unset = single shared dir, exactly as before."""
369
+
370
+ name = "file"
371
+
372
+ def __init__(self) -> None:
373
+ self._dir = Path(os.environ.get("AAT_SECRETS_DIR") or "/run/secrets/aat")
374
+
375
+ @staticmethod
376
+ def _safe(v: str) -> str | None:
377
+ s = re.sub(r"[^0-9A-Za-z._-]+", "-", (v or "").strip()).strip("-._")
378
+ return s if s and s not in (".", "..") else None
379
+
380
+ def _dirs(self) -> list[Path]:
381
+ """Search order, most specific first, mirroring userdata's ``(ws, user)``
382
+ layout (spec P0.0-01): ``ws/<ws>/<user>`` -> ``<user>`` -> ``ws/<ws>`` ->
383
+ shared. Unset AAT_WORKSPACE_ID/AAT_USER_ID falls straight through to the shared
384
+ dir, exactly the historical behaviour."""
385
+ dirs: list[Path] = []
386
+ ws = self._safe(os.environ.get("AAT_WORKSPACE_ID") or "")
387
+ uid = self._safe(os.environ.get("AAT_USER_ID") or "")
388
+ if ws and uid:
389
+ dirs.append(self._dir / "ws" / ws / uid) # per-(ws,user), highest priority
390
+ if uid:
391
+ dirs.append(self._dir / uid) # per-user
392
+ if ws:
393
+ dirs.append(self._dir / "ws" / ws) # per-workspace (shared in WS)
394
+ dirs.append(self._dir) # shared fallback
395
+ return dirs
396
+
397
+ def get_optional(self, tool: str, secret: str) -> str | None:
398
+ for d in self._dirs():
399
+ f = d / f"{tool}__{secret}"
400
+ if f.exists():
401
+ return f.read_text(encoding="utf-8").strip() or None
402
+ jf = d / "secrets.json"
403
+ if jf.exists():
404
+ try:
405
+ v = (json.loads(jf.read_text(encoding="utf-8")).get(tool) or {}).get(secret)
406
+ except ValueError:
407
+ v = None
408
+ if v is not None:
409
+ return str(v)
410
+ return None
411
+
412
+
413
+ class BridgeBackend(_ReadOnly):
414
+ """HTTP GET to a loopback host service that wraps Windows Credential Manager.
415
+ Lets a container on the laptop read host secrets without copying them (infra I1).
416
+ AAT_CREDS_BRIDGE_URL (default http://host.docker.internal:8903) + a bearer token
417
+ in AAT_CREDS_BRIDGE_TOKEN."""
418
+
419
+ name = "bridge"
420
+
421
+ def __init__(self) -> None:
422
+ self._url = (os.environ.get("AAT_CREDS_BRIDGE_URL")
423
+ or "http://host.docker.internal:8903").rstrip("/")
424
+ self._token = os.environ.get("AAT_CREDS_BRIDGE_TOKEN", "")
425
+ # In-container cache. The container's readiness scan checks every secret over
426
+ # the network and the model calls capabilities repeatedly; secrets don't change
427
+ # mid-session, so cache with a short TTL (AAT_CREDS_BRIDGE_TTL seconds, 0 = off).
428
+ # The value stays in memory only - already fetched on use.
429
+ self._cache: dict = {}
430
+ self._ttl = float(os.environ.get("AAT_CREDS_BRIDGE_TTL", "60") or 0)
431
+
432
+ def get_optional(self, tool: str, secret: str) -> str | None:
433
+ if self._ttl > 0:
434
+ hit = self._cache.get((tool, secret))
435
+ if hit is not None and hit[1] > time.monotonic():
436
+ return hit[0]
437
+ val = self._fetch(tool, secret)
438
+ if self._ttl > 0:
439
+ self._cache[(tool, secret)] = (val, time.monotonic() + self._ttl)
440
+ return val
441
+
442
+ def _fetch(self, tool: str, secret: str) -> str | None:
443
+ req = urllib.request.Request(
444
+ f"{self._url}/secret/{tool}/{secret}",
445
+ headers={"Authorization": f"Bearer {self._token}"} if self._token else {})
446
+ try:
447
+ with urllib.request.urlopen(req, timeout=5) as resp: # noqa: S310 (loopback)
448
+ body = resp.read().decode("utf-8").strip()
449
+ return body or None
450
+ except urllib.error.HTTPError as e:
451
+ # 404 is the ONE quiet outcome: the secret is genuinely absent, which
452
+ # is what get_optional promises to return None for. Every other code
453
+ # means "we could not answer the question" and must be loud - a
454
+ # refusal or an outage reported as None reaches the caller as
455
+ # "missing credential; run set-credential", sending someone to fix a
456
+ # store that is fine while the real cause goes unmentioned.
457
+ if e.code == 404:
458
+ return None
459
+ if e.code == 401:
460
+ raise RuntimeError(
461
+ f"creds bridge rejected the bearer token ({self._url}); "
462
+ "check AAT_CREDS_BRIDGE_TOKEN, or re-issue it with "
463
+ "`creds-bridge issue-token --force` and restart the bridge")
464
+ if e.code == 403:
465
+ raise RuntimeError(
466
+ f"creds bridge policy denies {tool}:{secret} ({self._url}); "
467
+ "widen 'allow' in the bridge's policy.json, or the host's "
468
+ "audit log will show the denial")
469
+ raise
470
+ except urllib.error.URLError as e:
471
+ raise RuntimeError(
472
+ f"creds bridge unreachable at {self._url} ({e.reason}); start it "
473
+ "on the host with `creds-bridge start`, or unset "
474
+ "AAT_CREDS_BACKEND to use this machine's own vault")
475
+
476
+
477
+ class ProcesioBackend(_ReadOnly):
478
+ """Resolve a secret from the PROCESIO credential store for the active
479
+ ``(workspace, user)`` (spec P0.0-08). Structurally identical to ``BridgeBackend``:
480
+ a read-only, TTL-cached HTTP GET to a resolver endpoint. The endpoint maps AAT's
481
+ ``(tool, secret)`` identity to a PROCESIO ``CREDENTIALS`` row in the caller's
482
+ workspace and returns the decrypted value; nothing is written from a worker.
483
+
484
+ Config: ``AAT_PROCESIO_CREDS_URL`` (resolver base), ``AAT_PROCESIO_CREDS_TOKEN``
485
+ (bearer), ``AAT_CREDS_PROCESIO_TTL`` (cache seconds, default 60). The active
486
+ ``(workspace, user)`` are sent as ``X-AAT-Workspace`` / ``X-AAT-User`` headers
487
+ (server-established env, item P0.0-01), so the endpoint scopes the lookup - incl.
488
+ the personal-workspace ``(WS=Empty, User)`` case. Import-safe on any OS."""
489
+
490
+ name = "procesio"
491
+
492
+ def __init__(self) -> None:
493
+ self._url = (os.environ.get("AAT_PROCESIO_CREDS_URL")
494
+ or "http://localhost:8904").rstrip("/")
495
+ self._token = os.environ.get("AAT_PROCESIO_CREDS_TOKEN", "")
496
+ self._cache: dict = {}
497
+ self._ttl = float(os.environ.get("AAT_CREDS_PROCESIO_TTL", "60") or 0)
498
+
499
+ def _headers(self) -> dict:
500
+ h = {}
501
+ if self._token:
502
+ h["Authorization"] = f"Bearer {self._token}"
503
+ ws = (os.environ.get("AAT_WORKSPACE_ID") or "").strip()
504
+ uid = (os.environ.get("AAT_USER_ID") or "").strip()
505
+ if ws:
506
+ h["X-AAT-Workspace"] = ws
507
+ if uid:
508
+ h["X-AAT-User"] = uid
509
+ return h
510
+
511
+ def get_optional(self, tool: str, secret: str) -> str | None:
512
+ # Cache key includes (ws,user) so a pooled worker serving many tenants never
513
+ # returns one tenant's secret to another.
514
+ ck = (os.environ.get("AAT_WORKSPACE_ID", ""), os.environ.get("AAT_USER_ID", ""),
515
+ tool, secret)
516
+ if self._ttl > 0:
517
+ hit = self._cache.get(ck)
518
+ if hit is not None and hit[1] > time.monotonic():
519
+ return hit[0]
520
+ val = self._fetch(tool, secret)
521
+ if self._ttl > 0:
522
+ self._cache[ck] = (val, time.monotonic() + self._ttl)
523
+ return val
524
+
525
+ def _fetch(self, tool: str, secret: str) -> str | None:
526
+ req = urllib.request.Request(
527
+ f"{self._url}/credential/{tool}/{secret}", headers=self._headers())
528
+ try:
529
+ with urllib.request.urlopen(req, timeout=10) as resp: # noqa: S310
530
+ body = resp.read().decode("utf-8").strip()
531
+ return body or None
532
+ except urllib.error.HTTPError as e:
533
+ if e.code == 404:
534
+ return None
535
+ raise
536
+ except urllib.error.URLError:
537
+ return None
538
+
539
+
540
+ _ALIASES = {
541
+ "windows": "windows", "winvault": "windows", "win32": "windows",
542
+ "macos": "macos", "mac": "macos", "keychain": "macos", "osx": "macos", "darwin": "macos",
543
+ "linux": "linux", "secretservice": "linux", "secret-service": "linux",
544
+ "kwallet": "linux", "gnome-keyring": "linux",
545
+ "encrypted-file": "encrypted-file", "encryptedfile": "encrypted-file",
546
+ "encrypted": "encrypted-file",
547
+ "env": "env", "envjson": "env", "env-json": "env",
548
+ "file": "file", "file-secret": "file", "filesecret": "file",
549
+ "bridge": "bridge",
550
+ "procesio": "procesio",
551
+ }
552
+ _CTORS = {"windows": WindowsBackend, "macos": MacKeychainBackend,
553
+ "linux": LinuxSecretServiceBackend, "encrypted-file": EncryptedFileBackend,
554
+ "env": EnvJsonBackend, "file": FileSecretBackend, "bridge": BridgeBackend,
555
+ "procesio": ProcesioBackend}
556
+
557
+ # Every backend name a caller may pass, in one place, so the factory's error message
558
+ # cannot drift from what the factory actually accepts (it used to be a hand-kept
559
+ # literal that already omitted 'macos').
560
+ KNOWN = tuple(sorted(_CTORS))
561
+
562
+
563
+ def default_backend_name() -> str:
564
+ """The backend used when AAT_CREDS_BACKEND is unset: the OS-native secret store.
565
+
566
+ macOS -> login Keychain; Windows (incl. Claude Code) -> Credential Manager;
567
+ everything else -> the Linux desktop keyring. A function, not a module constant,
568
+ so a test can exercise the mapping for a platform it is not running on."""
569
+ return {"darwin": "macos", "win32": "windows"}.get(sys.platform, "linux")
570
+
571
+
572
+ def make(name: str | None) -> Backend:
573
+ requested = (name or "").strip().lower() or default_backend_name()
574
+ key = _ALIASES.get(requested)
575
+ if key is None:
576
+ raise ValueError(
577
+ f"unknown AAT_CREDS_BACKEND {name!r}; use one of: " + ", ".join(KNOWN))
578
+ return _CTORS[key]() # type: ignore[return-value]