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,211 @@
1
+ """Setup actions the dashboard performs on the user's behalf.
2
+
3
+ Everything a colleague would otherwise do in a terminal or a chat: store/delete
4
+ credentials, seed the user-data folder, edit validated config, capture a web
5
+ login, run an OAuth flow. Secrets flow browser -> loopback POST -> the existing
6
+ set-credential script (stdin) -> Windows Credential Manager; they are never
7
+ logged, echoed, or written to disk here. Config edits and jobs stay under
8
+ context-state-knowledge/ via userdata, preserving the wipe-safe boundary.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ from agents.orchestrator import bootstraplib
17
+ from tools._lib import userdata
18
+
19
+ from . import config_schemas, inventory, jobs, runner
20
+
21
+
22
+ def _resolve_secret(tool: str, secret: str) -> tuple[str, str]:
23
+ """A `namespace:name` secret (e.g. google:oauth-client) is stored under the
24
+ namespace, matching registry._has_secret. Everything else stays as-is."""
25
+ if ":" in secret:
26
+ ns, _, name = secret.partition(":")
27
+ return ns, name
28
+ return tool, secret
29
+
30
+
31
+ # ---- credentials --------------------------------------------------------
32
+ def credential_set(req) -> Any:
33
+ tool = (req.body.get("tool") or "").strip()
34
+ secret = (req.body.get("secret") or "").strip()
35
+ value = req.body.get("value")
36
+ if not tool or not secret:
37
+ return (400, {"error": "tool and secret are required"})
38
+ if not value or not str(value).strip():
39
+ return (400, {"error": "value is empty"})
40
+ rtool, rsecret = _resolve_secret(tool, secret)
41
+ res = runner.set_credential(rtool, rsecret, str(value))
42
+ if res["ok"]:
43
+ inventory.invalidate()
44
+ # res["message"] is set-credential's own output ("stored: ... (N bytes)") -
45
+ # it never contains the secret value.
46
+ return {"ok": res["ok"], "message": res["message"], "tool": tool, "secret": secret}
47
+
48
+
49
+ def credential_delete(req) -> Any:
50
+ tool = (req.body.get("tool") or "").strip()
51
+ secret = (req.body.get("secret") or "").strip()
52
+ if not tool or not secret:
53
+ return (400, {"error": "tool and secret are required"})
54
+ rtool, rsecret = _resolve_secret(tool, secret)
55
+ res = runner.delete_credential(rtool, rsecret)
56
+ if res["ok"]:
57
+ inventory.invalidate()
58
+ return {"ok": res["ok"], "message": res["message"]}
59
+
60
+
61
+ def credential_check(req) -> Any:
62
+ tool = (req.q("tool") or "").strip()
63
+ secret = (req.q("secret") or "").strip()
64
+ if not tool or not secret:
65
+ return (400, {"error": "tool and secret are required"})
66
+ rtool, rsecret = _resolve_secret(tool, secret)
67
+ return {"present": runner.check_credential(rtool, rsecret)}
68
+
69
+
70
+ # ---- bootstrap ----------------------------------------------------------
71
+ def bootstrap(req) -> Any:
72
+ # Seeding the user-data folder is the orchestrator's job. Not every
73
+ # distribution of this framework ships that agent, and a missing agent came
74
+ # back as a bare 500 that read like the dashboard was broken.
75
+ import registry
76
+ try:
77
+ registry.get_agent("orchestrator")
78
+ except KeyError:
79
+ return (501, {"error": "bootstrap is not available in this installation",
80
+ "detail": "the orchestrator agent, which seeds the user-data "
81
+ "folder, is not installed here. Credentials and "
82
+ "config can still be set from this page."})
83
+ with_templates = bool(req.body.get("with_templates", True))
84
+ argv = ["bootstrap"] + (["--with-templates"] if with_templates else [])
85
+ res = runner.run_agent("orchestrator", argv, timeout=90)
86
+ if res["ok"]:
87
+ inventory.invalidate()
88
+ return res["data"]
89
+ return (500, {"error": "bootstrap failed", "detail": res["error"]})
90
+
91
+
92
+ # ---- config editor ------------------------------------------------------
93
+ def _config_path(component: str, name: str) -> Path:
94
+ # config_dir sanitizes the component; name is constrained to a bare filename.
95
+ safe_name = "".join(c for c in name if c.isalnum() or c in "._-")
96
+ return userdata.config_dir(component) / f"{safe_name}.json"
97
+
98
+
99
+ def config_list(req) -> Any:
100
+ """Every framework config template + whether the user's copy exists."""
101
+ out = []
102
+ for t in bootstraplib.find_templates():
103
+ component = t["component"]
104
+ name = Path(t["target"]).stem
105
+ out.append({
106
+ "component": component,
107
+ "name": name,
108
+ "template": t["template"],
109
+ "exists": t["target_exists"],
110
+ "has_schema": config_schemas.has_schema(component, name),
111
+ })
112
+ return {"configs": out}
113
+
114
+
115
+ def config_get(req) -> Any:
116
+ component = (req.q("component") or "").strip()
117
+ name = (req.q("name") or "").strip()
118
+ if not component or not name:
119
+ return (400, {"error": "component and name are required"})
120
+ path = _config_path(component, name)
121
+ data, err = None, None
122
+ if path.exists():
123
+ try:
124
+ data = json.loads(path.read_text(encoding="utf-8"))
125
+ except ValueError as e:
126
+ err = f"existing file is not valid JSON: {e}"
127
+ # the framework template, for reference / starting point
128
+ tpl = None
129
+ for t in bootstraplib.find_templates():
130
+ if t["component"] == component and Path(t["target"]).stem == name:
131
+ tpl_path = bootstraplib.FRAMEWORK_ROOT / t["template"]
132
+ try:
133
+ tpl = json.loads(tpl_path.read_text(encoding="utf-8"))
134
+ except (OSError, ValueError):
135
+ tpl = None
136
+ break
137
+ return {"component": component, "name": name, "exists": path.exists(),
138
+ "data": data, "template": tpl, "read_error": err,
139
+ "has_schema": config_schemas.has_schema(component, name)}
140
+
141
+
142
+ def config_validate(req) -> Any:
143
+ component = (req.body.get("component") or "").strip()
144
+ name = (req.body.get("name") or "").strip()
145
+ return config_schemas.validate(component, name, req.body.get("data"))
146
+
147
+
148
+ def config_set(req) -> Any:
149
+ component = (req.body.get("component") or "").strip()
150
+ name = (req.body.get("name") or "").strip()
151
+ data = req.body.get("data")
152
+ if not component or not name:
153
+ return (400, {"error": "component and name are required"})
154
+ verdict = config_schemas.validate(component, name, data)
155
+ if not verdict["ok"]:
156
+ return (400, {"error": "validation failed", "errors": verdict["errors"]})
157
+ path = _config_path(component, name)
158
+ path.parent.mkdir(parents=True, exist_ok=True)
159
+ text = json.dumps(data, ensure_ascii=False, indent=2) + "\n"
160
+ path.write_bytes(text.encode("utf-8")) # bytes+LF: no Windows CRLF flip
161
+ inventory.invalidate()
162
+ return {"ok": True, "path": str(path), "warnings": verdict["warnings"]}
163
+
164
+
165
+ # ---- web session capture ------------------------------------------------
166
+ def session_start(req) -> Any:
167
+ name = (req.body.get("name") or "").strip()
168
+ url = (req.body.get("url") or "").strip()
169
+ if not name or not url:
170
+ return (400, {"error": "name and url are required"})
171
+ argv = ["run-tool.py", "web", "save-session", "--name", name, "--url", url]
172
+ if req.body.get("channel"):
173
+ argv += ["--channel", str(req.body["channel"])]
174
+ if req.body.get("persistent"):
175
+ argv += ["--persistent"]
176
+ job = jobs.create("session", argv, stdin_signal=True)
177
+ return job.snapshot()
178
+
179
+
180
+ def session_commit(req) -> Any:
181
+ """The user has logged in; send the ENTER the save-session is blocking on and
182
+ wait for it to persist and exit."""
183
+ job = jobs.get((req.body.get("job_id") or "").strip())
184
+ if job is None:
185
+ return (404, {"error": "unknown job"})
186
+ if not job.signal():
187
+ return (409, {"error": "job is not awaiting a login signal",
188
+ "status": job.status})
189
+ job.wait(90)
190
+ inventory.invalidate()
191
+ return job.snapshot()
192
+
193
+
194
+ # ---- OAuth --------------------------------------------------------------
195
+ def oauth_start(req) -> Any:
196
+ tool = (req.body.get("tool") or "").strip()
197
+ if not tool:
198
+ return (400, {"error": "tool is required"})
199
+ # google-*/linkedin expose auth-login; it opens a browser and self-completes
200
+ # on the localhost redirect, so no stdin signal is needed.
201
+ job = jobs.create("oauth", ["run-tool.py", tool, "auth-login"], stdin_signal=False)
202
+ return job.snapshot()
203
+
204
+
205
+ def job_get(req) -> Any:
206
+ job = jobs.get((req.q("id") or "").strip())
207
+ if job is None:
208
+ return (404, {"error": "unknown job"})
209
+ if job.status in ("done", "failed"):
210
+ inventory.invalidate()
211
+ return job.snapshot()
@@ -0,0 +1,152 @@
1
+ """Live credential validation - the 'is it actually connected?' truth.
2
+
3
+ Presence (secret exists in Credential Manager) comes free from the registry. This
4
+ layer goes further: it runs a cheap, read-only probe and reports CONNECTED /
5
+ INVALID / UNKNOWN.
6
+
7
+ Probe resolution per capability:
8
+ 1. explicit `healthcheck:` in the manifest -> run that action, success = connected
9
+ 2. else a conventional `auth-status` action -> run it; its `ready` field decides
10
+ 3. else -> UNKNOWN (no way to probe)
11
+
12
+ We only probe when every required secret is already present - a capability with
13
+ missing creds is already known-unconfigured, so we skip the call (no point proving
14
+ the obvious, and it keeps 'validate everything on load' fast). Probes run
15
+ concurrently and stream back as they finish.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import threading
20
+ import time
21
+ from concurrent.futures import ThreadPoolExecutor
22
+ from typing import Any, Iterator
23
+
24
+ import registry
25
+
26
+ from . import runner
27
+
28
+ _MAX_WORKERS = 6
29
+ _CACHE_TTL = 20.0
30
+ _PROBE_TIMEOUT = 12.0 # a dead/unreachable system (e.g. VPN-gated) fails fast
31
+ _cache: dict[str, tuple[float, dict]] = {}
32
+ _lock = threading.Lock()
33
+ # Single-flight: only one full sweep runs at a time. A second concurrent
34
+ # request (e.g. a reconnecting client) is served the current cache snapshot
35
+ # instead of storming the machine with a second wave of subprocesses.
36
+ _sweep_lock = threading.Lock()
37
+
38
+
39
+ def _index() -> dict[str, dict]:
40
+ """kind:name -> registry entry, for tools and agents."""
41
+ idx = {}
42
+ for t in registry.list_tools():
43
+ idx["tool:" + t["name"]] = t
44
+ for a in registry.list_agents():
45
+ idx["agent:" + a["name"]] = a
46
+ return idx
47
+
48
+
49
+ def _probe_argv(entry: dict) -> list[str] | None:
50
+ """The argv to run for this entry's probe, or None if it has none."""
51
+ hc = entry.get("healthcheck")
52
+ if hc:
53
+ action = hc.get("action") or ""
54
+ argv = [action] if action else []
55
+ argv += runner.flags_from(hc.get("args") or {})
56
+ return argv
57
+ actions = {a["name"] for a in entry.get("actions", [])}
58
+ if "auth-status" in actions:
59
+ return ["auth-status"]
60
+ return None
61
+
62
+
63
+ def _interpret(entry: dict, argv: list[str], result: dict) -> dict:
64
+ """Map a probe run to {status, detail}."""
65
+ using_authstatus = argv == ["auth-status"] and not entry.get("healthcheck")
66
+ if result["ok"]:
67
+ data = result.get("data")
68
+ # auth-status tools report their own readiness; honor it.
69
+ if using_authstatus and isinstance(data, dict) and "ready" in data and not data["ready"]:
70
+ return {"status": "invalid",
71
+ "detail": "auth-status reports not ready: " + _short(data)}
72
+ return {"status": "connected", "detail": _short(data) if isinstance(data, dict) else ""}
73
+ err = result.get("error") or {}
74
+ return {"status": "invalid", "detail": (err.get("message") or err.get("code") or "probe failed")[:300]}
75
+
76
+
77
+ def _short(data: dict) -> str:
78
+ keep = {k: v for k, v in list(data.items())[:6]
79
+ if isinstance(v, (str, int, float, bool)) and k not in ("error",)}
80
+ return ", ".join(f"{k}={v}" for k, v in keep.items())[:300]
81
+
82
+
83
+ def probe(key: str, entry: dict, *, force: bool = False) -> dict:
84
+ """Run (or serve from cache) the probe for one capability."""
85
+ if not force:
86
+ with _lock:
87
+ hit = _cache.get(key)
88
+ if hit and (time.time() - hit[0]) < _CACHE_TTL:
89
+ return hit[1]
90
+
91
+ if entry.get("error"):
92
+ res = {"kind": key.split(":")[0], "name": entry["name"],
93
+ "status": "unknown", "detail": "manifest error"}
94
+ elif entry.get("missing_secrets"):
95
+ res = {"kind": key.split(":")[0], "name": entry["name"], "status": "unknown",
96
+ "detail": "credentials not set: " + ", ".join(entry["missing_secrets"])}
97
+ else:
98
+ argv = _probe_argv(entry)
99
+ if argv is None:
100
+ res = {"kind": key.split(":")[0], "name": entry["name"],
101
+ "status": "unknown", "detail": "no healthcheck or auth-status"}
102
+ else:
103
+ run = runner.run_tool(entry["name"], argv, timeout=_PROBE_TIMEOUT)
104
+ verdict = _interpret(entry, argv, run)
105
+ res = {"kind": key.split(":")[0], "name": entry["name"], **verdict}
106
+ with _lock:
107
+ _cache[key] = (time.time(), res)
108
+ return res
109
+
110
+
111
+ def stream_all(req) -> Iterator[tuple[str, dict]]:
112
+ """Probe every capability that CAN be probed, concurrently, yielding each
113
+ result as it lands. Items with no probe or missing creds resolve instantly."""
114
+ idx = _index()
115
+ force = req.q("force") in ("1", "true", "yes")
116
+ targets = list(idx.items())
117
+
118
+ # Single-flight: if a sweep is already running, don't launch a second wave -
119
+ # stream whatever the cache currently holds and return.
120
+ if not _sweep_lock.acquire(blocking=False):
121
+ for k, e in targets:
122
+ with _lock:
123
+ hit = _cache.get(k)
124
+ yield ("result", hit[1] if hit else
125
+ {"kind": k.split(":")[0], "name": k.split(":", 1)[1],
126
+ "status": "checking", "detail": "another check in progress"})
127
+ return
128
+ try:
129
+ with ThreadPoolExecutor(max_workers=_MAX_WORKERS) as pool:
130
+ futs = {pool.submit(probe, k, e, force=force): k for k, e in targets}
131
+ from concurrent.futures import as_completed
132
+ for fut in as_completed(futs):
133
+ try:
134
+ yield ("result", fut.result())
135
+ except Exception as e: # noqa: BLE001
136
+ k = futs[fut]
137
+ yield ("result", {"kind": k.split(":")[0], "name": k.split(":", 1)[1],
138
+ "status": "invalid", "detail": str(e)[:200]})
139
+ finally:
140
+ _sweep_lock.release()
141
+
142
+
143
+ def validate_one_route(req) -> dict:
144
+ """POST {kind, name} -> fresh probe for a single capability (bypasses cache)."""
145
+ kind = (req.body.get("kind") or "").strip()
146
+ name = (req.body.get("name") or "").strip()
147
+ key = f"{kind}:{name}"
148
+ idx = _index()
149
+ entry = idx.get(key)
150
+ if entry is None:
151
+ return (404, {"error": "unknown capability", "key": key})
152
+ return probe(key, entry, force=True)
@@ -0,0 +1,16 @@
1
+ """Test setup for the dashboard package.
2
+
3
+ Puts the repo root on sys.path (so `import dashboard...` / `import registry`
4
+ resolve under importlib mode) and forces keyring's Windows backend to skip the
5
+ auto-detection that can block in a console-less process.
6
+ """
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ _ROOT = Path(__file__).resolve().parents[2]
12
+ if str(_ROOT) not in sys.path:
13
+ sys.path.insert(0, str(_ROOT))
14
+
15
+ os.environ.setdefault("PYTHON_KEYRING_BACKEND",
16
+ "keyring.backends.Windows.WinVaultKeyring")
@@ -0,0 +1,225 @@
1
+ """Dashboard tests - hermetic units + one in-process server smoke.
2
+
3
+ Network/subprocess-touching pieces (validation probes, credential writes) are
4
+ monkeypatched so the suite is fast and side-effect free.
5
+ """
6
+ import json
7
+ import threading
8
+ import urllib.error
9
+ import urllib.request
10
+ from http.server import ThreadingHTTPServer
11
+
12
+ import pytest
13
+
14
+ from dashboard.server import (config_schemas, google, handler, inventory,
15
+ routes, security, setup, validate)
16
+
17
+
18
+ class _Req:
19
+ def __init__(self, body=None, query=None):
20
+ self.body = body or {}
21
+ self._q = query or {}
22
+
23
+ def q(self, name, default=None):
24
+ return self._q.get(name, default)
25
+
26
+
27
+ # ---- config_schemas -----------------------------------------------------
28
+ def test_llm_schema_rejects_bad_adapter():
29
+ v = config_schemas.validate("llm", "providers",
30
+ {"providers": {"x": {"adapter": "nope"}}})
31
+ assert not v["ok"]
32
+ assert any("adapter" in e for e in v["errors"])
33
+
34
+
35
+ def test_llm_schema_default_must_exist():
36
+ v = config_schemas.validate("llm", "providers", {
37
+ "providers": {"openai": {"adapter": "openai_compat"}}, "default": "ghost"})
38
+ assert not v["ok"]
39
+ assert any("default" in e for e in v["errors"])
40
+
41
+
42
+ def test_llm_schema_accepts_good():
43
+ v = config_schemas.validate("llm", "providers", {
44
+ "providers": {"openai": {"adapter": "openai_compat", "model": "gpt-4o"}},
45
+ "default": "openai"})
46
+ assert v["ok"] and not v["warnings"]
47
+
48
+
49
+ def test_placeholder_is_a_warning_not_error():
50
+ v = config_schemas.validate("anything", "cfg", {"host": "YOUR-HOST"})
51
+ assert v["ok"]
52
+ assert any("placeholder" in w for w in v["warnings"])
53
+
54
+
55
+ def test_non_object_config_rejected():
56
+ v = config_schemas.validate("x", "y", [1, 2, 3])
57
+ assert not v["ok"]
58
+
59
+
60
+ # ---- secret namespace resolution ---------------------------------------
61
+ def test_namespaced_secret_resolves_to_namespace():
62
+ assert setup._resolve_secret("google-mail", "google:oauth-client") == (
63
+ "google", "oauth-client")
64
+ assert setup._resolve_secret("ryver", "token") == ("ryver", "token")
65
+
66
+
67
+ # ---- validation interpretation (monkeypatched runner) -------------------
68
+ def test_probe_skips_when_secret_missing():
69
+ entry = {"name": "t", "missing_secrets": ["token"], "actions": []}
70
+ res = validate.probe("tool:t", entry, force=True)
71
+ assert res["status"] == "unknown" and "credentials not set" in res["detail"]
72
+
73
+
74
+ def test_probe_connected_on_healthcheck_ok(monkeypatch):
75
+ monkeypatch.setattr(validate.runner, "run_tool",
76
+ lambda *a, **k: {"ok": True, "data": {"count": 3}, "error": None})
77
+ entry = {"name": "t", "missing_secrets": [],
78
+ "healthcheck": {"action": "ping", "args": {}}, "actions": []}
79
+ res = validate.probe("tool:t", entry, force=True)
80
+ assert res["status"] == "connected"
81
+
82
+
83
+ def test_probe_invalid_on_authstatus_not_ready(monkeypatch):
84
+ monkeypatch.setattr(validate.runner, "run_tool",
85
+ lambda *a, **k: {"ok": True, "data": {"ready": False}, "error": None})
86
+ entry = {"name": "t", "missing_secrets": [], "healthcheck": None,
87
+ "actions": [{"name": "auth-status"}]}
88
+ res = validate.probe("tool:t", entry, force=True)
89
+ assert res["status"] == "invalid"
90
+
91
+
92
+ def test_probe_invalid_on_error(monkeypatch):
93
+ monkeypatch.setattr(validate.runner, "run_tool",
94
+ lambda *a, **k: {"ok": False, "data": None,
95
+ "error": {"code": "x", "message": "bad key"}})
96
+ entry = {"name": "t", "missing_secrets": [], "healthcheck": {"action": "ping"},
97
+ "actions": []}
98
+ res = validate.probe("tool:t", entry, force=True)
99
+ assert res["status"] == "invalid" and "bad key" in res["detail"]
100
+
101
+
102
+ # ---- google multi-account -----------------------------------------------
103
+ def test_google_label_validation():
104
+ assert google._valid_label("personal")
105
+ assert google._valid_label("work-2")
106
+ assert not google._valid_label("bad@email")
107
+ assert not google._valid_label("UPPER")
108
+ assert not google._valid_label("")
109
+
110
+
111
+ def test_google_login_builds_account_argv(monkeypatch):
112
+ captured = {}
113
+
114
+ class FakeJob:
115
+ def snapshot(self):
116
+ return {"id": "x", "status": "running"}
117
+
118
+ def fake_create(kind, argv, stdin_signal=False):
119
+ captured["argv"] = argv
120
+ return FakeJob()
121
+
122
+ monkeypatch.setattr(google.jobs, "create", fake_create)
123
+ google.login(_Req({"account": "work"}))
124
+ assert captured["argv"] == ["run-tool.py", "google-mail", "auth-login", "--account", "work"]
125
+ captured.clear()
126
+ google.login(_Req({"account": "default"})) # default -> no --account
127
+ assert captured["argv"] == ["run-tool.py", "google-mail", "auth-login"]
128
+
129
+
130
+ def test_google_login_rejects_email_label():
131
+ res = google.login(_Req({"account": "a@example.com"}))
132
+ assert isinstance(res, tuple) and res[0] == 400
133
+
134
+
135
+ def test_google_remove_builds_logout_argv(monkeypatch):
136
+ captured = {}
137
+
138
+ def fake_run(tool, argv, timeout=30):
139
+ captured["argv"] = argv
140
+ return {"ok": True, "data": {"authenticated": False}, "error": None}
141
+
142
+ monkeypatch.setattr(google.runner, "run_tool", fake_run)
143
+ monkeypatch.setattr(google.inventory, "invalidate", lambda: None)
144
+ google.remove(_Req({"account": "personal"}))
145
+ assert captured["argv"] == ["auth-logout", "--account", "personal"]
146
+
147
+
148
+ def test_google_accounts_fast_no_email(monkeypatch):
149
+ def fake_run(tool, argv, timeout=30):
150
+ assert argv == ["auth-accounts"] # the fast list makes no get-profile call
151
+ return {"ok": True, "error": None, "data": {"active": "default", "accounts": [
152
+ {"account": "default", "has_token": True},
153
+ {"account": "personal", "has_token": True}]}}
154
+ monkeypatch.setattr(google.runner, "run_tool", fake_run)
155
+ out = google.accounts(_Req())
156
+ assert out["ok"] and out["active"] == "default"
157
+ assert [a["account"] for a in out["accounts"]] == ["default", "personal"]
158
+ assert out["accounts"][0]["active"] and not out["accounts"][1]["active"]
159
+ assert "email" not in out["accounts"][0] # email is lazy, not in the list
160
+
161
+
162
+ # ---- in-process server: auth gate + routing -----------------------------
163
+ @pytest.fixture()
164
+ def server():
165
+ srv = ThreadingHTTPServer(("127.0.0.1", 0), handler.Handler)
166
+ srv.daemon_threads = True
167
+ threading.Thread(target=srv.serve_forever, daemon=True).start()
168
+ yield f"http://127.0.0.1:{srv.server_address[1]}", security.token()
169
+ srv.shutdown()
170
+
171
+
172
+ def _call(base, path, token=None, method="GET", body=None):
173
+ headers = {"Content-Type": "application/json"}
174
+ if token:
175
+ headers["X-Dashboard-Token"] = token
176
+ data = json.dumps(body).encode() if body is not None else None
177
+ req = urllib.request.Request(base + path, method=method, data=data, headers=headers)
178
+ try:
179
+ r = urllib.request.urlopen(req, timeout=30)
180
+ return r.status, json.loads(r.read())
181
+ except urllib.error.HTTPError as e:
182
+ return e.code, json.loads(e.read())
183
+
184
+
185
+ def test_api_requires_token(server):
186
+ base, _ = server
187
+ status, _ = _call(base, "/api/health")
188
+ assert status == 401
189
+
190
+
191
+ def test_health_ok_with_token(server):
192
+ base, tok = server
193
+ status, body = _call(base, "/api/health", token=tok)
194
+ assert status == 200 and body["ok"] is True
195
+
196
+
197
+ def test_static_index_served_without_token(server):
198
+ base, _ = server
199
+ req = urllib.request.Request(base + "/")
200
+ r = urllib.request.urlopen(req, timeout=10)
201
+ assert r.status == 200 and b"Setup" in r.read()
202
+
203
+
204
+ def test_unknown_api_route_404(server):
205
+ base, tok = server
206
+ status, _ = _call(base, "/api/nope", token=tok)
207
+ assert status == 404
208
+
209
+
210
+ def test_routes_wired():
211
+ for p in ("/api/inventory", "/api/config/list", "/api/context/inspect"):
212
+ assert routes.resolve("GET", p) is not None
213
+ for p in ("/api/credential/set", "/api/validate/one", "/api/copilot",
214
+ "/api/test/tool"):
215
+ assert routes.resolve("POST", p) is not None
216
+
217
+
218
+ # ---- inventory shape (real registry; slower integration check) ----------
219
+ def test_inventory_shape():
220
+ inv = inventory.build(force=True)
221
+ assert set(("summary", "tools", "agents", "skills", "providers")) <= set(inv)
222
+ assert inv["summary"]["tools"]["total"] >= 1
223
+ # every tool entry carries the annotations the UI relies on
224
+ sample = inv["tools"][0]
225
+ assert "secrets_status" in sample and "probe" in sample and "kind" in sample