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,103 @@
1
+ """Google multi-account (profile) management for the dashboard.
2
+
3
+ The 8 Google tools share one OAuth credential set under the `google:` namespace
4
+ and support MULTIPLE accounts, each keyed by an arbitrary lowercase LABEL
5
+ (`default`, `personal`, `work`, ...) - NOT by email. Only `google-mail` (and
6
+ `google-contacts`) expose the `--account` surface + `auth-accounts`, and the token
7
+ they write is shared by every Google tool, so we drive ALL account operations
8
+ through `google-mail`.
9
+
10
+ list -> google-mail auth-accounts (+ best-effort email via get-profile)
11
+ add /
12
+ re-auth-> google-mail auth-login --account (BLOCKS on browser consent -> a job)
13
+ remove -> google-mail auth-logout --account (fast)
14
+
15
+ The OAuth CLIENT (google:oauth-client) is a precondition the user provisions as a
16
+ normal credential (the card's client-key row); we only manage the per-account
17
+ tokens here.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import re
22
+ from typing import Any
23
+
24
+ from . import inventory, jobs, runner
25
+
26
+ _DRIVER = "google-mail"
27
+ _LABEL_RE = re.compile(r"^[a-z0-9._-]+$")
28
+
29
+
30
+ def _valid_label(label: str) -> bool:
31
+ return bool(_LABEL_RE.match(label))
32
+
33
+
34
+ def _account_args(action_argv: list[str], label: str) -> list[str]:
35
+ """--account goes AFTER the action (a global flag stripped by the tool)."""
36
+ argv = list(action_argv)
37
+ if label:
38
+ argv += ["--account", label]
39
+ return argv
40
+
41
+
42
+ def accounts(req) -> Any:
43
+ """List connected Google profiles - fast (labels only, no network). The email
44
+ for each is fetched lazily by the UI via /api/google/email so the list appears
45
+ instantly instead of blocking on a get-profile call per account."""
46
+ r = runner.run_tool(_DRIVER, ["auth-accounts"], timeout=30)
47
+ if not r["ok"]:
48
+ # Most common cause: the OAuth client isn't stored yet.
49
+ st = runner.run_tool(_DRIVER, ["auth-status"], timeout=20)
50
+ has_client = bool(st["ok"] and (st["data"] or {}).get("has_client"))
51
+ return {"ok": False, "has_client": has_client,
52
+ "accounts": [], "error": r["error"]}
53
+ data = r["data"] or {}
54
+ active = data.get("active")
55
+ out = [{"account": a.get("account"), "has_token": bool(a.get("has_token")),
56
+ "active": a.get("account") == active}
57
+ for a in data.get("accounts", [])]
58
+ return {"ok": True, "active": active, "accounts": out}
59
+
60
+
61
+ def email(req) -> Any:
62
+ """Resolve one account's email address (a live get-profile call). Lazy, so a
63
+ slow or failing account never blocks the account list."""
64
+ label = (req.q("account") or "").strip().lower()
65
+ if not label or not _valid_label(label):
66
+ return (400, {"error": "invalid account"})
67
+ pr = runner.run_tool(_DRIVER, ["get-profile", "--account", label], timeout=25)
68
+ if pr["ok"] and isinstance(pr["data"], dict):
69
+ return {"account": label,
70
+ "email": pr["data"].get("emailAddress") or pr["data"].get("email")}
71
+ return {"account": label, "email": None,
72
+ "error": (pr.get("error") or {}).get("message")}
73
+
74
+
75
+ def login(req) -> Any:
76
+ """Add a new profile or re-authorize an existing one (same command). Runs as a
77
+ job because auth-login opens a browser and blocks until the user consents."""
78
+ label = (req.body.get("account") or "default").strip().lower()
79
+ if not _valid_label(label):
80
+ return (400, {"error": "invalid label",
81
+ "message": "Use a short label like 'personal' or 'work' "
82
+ "(lowercase letters, digits, . _ - ). Not an email."})
83
+ argv = ["run-tool.py", _DRIVER] + _account_args(["auth-login"],
84
+ "" if label == "default" else label)
85
+ job = jobs.create("google-oauth", argv, stdin_signal=False)
86
+ snap = job.snapshot()
87
+ snap["account"] = label
88
+ return snap
89
+
90
+
91
+ def remove(req) -> Any:
92
+ """Remove ONE profile's token (leaves the shared oauth-client intact)."""
93
+ label = (req.body.get("account") or "").strip().lower()
94
+ if not label:
95
+ return (400, {"error": "account label is required"})
96
+ if not _valid_label(label):
97
+ return (400, {"error": "invalid label"})
98
+ argv = _account_args(["auth-logout"], "" if label == "default" else label)
99
+ r = runner.run_tool(_DRIVER, argv, timeout=30)
100
+ if r["ok"]:
101
+ inventory.invalidate()
102
+ return {"ok": True, "account": label, "data": r["data"]}
103
+ return {"ok": False, "account": label, "error": r["error"]}
@@ -0,0 +1,160 @@
1
+ """HTTP request handler: routing, token gate, JSON + SSE + static serving.
2
+
3
+ Stdlib only. Domain logic lives in inventory/validate/setup/llmtest; this module
4
+ just parses the request, enforces the loopback token on /api/*, dispatches, and
5
+ serializes the response. Route handlers are imported lazily inside each branch so
6
+ the server boots even while later-milestone modules are still being added.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import traceback
12
+ from http.server import BaseHTTPRequestHandler
13
+ from pathlib import Path
14
+ from urllib.parse import parse_qs, urlparse
15
+
16
+ from . import security
17
+
18
+ WEB_DIR = Path(__file__).resolve().parents[1] / "web"
19
+
20
+ _CTYPES = {".html": "text/html; charset=utf-8",
21
+ ".js": "application/javascript; charset=utf-8",
22
+ ".css": "text/css; charset=utf-8",
23
+ ".svg": "image/svg+xml", ".ico": "image/x-icon"}
24
+
25
+
26
+ class Req:
27
+ """Minimal parsed-request view passed to route handlers."""
28
+ def __init__(self, method: str, path: str, query: dict, body: dict | None):
29
+ self.method = method
30
+ self.path = path
31
+ self.query = query
32
+ self.body = body or {}
33
+
34
+ def q(self, name: str, default=None):
35
+ v = self.query.get(name)
36
+ return v[0] if isinstance(v, list) and v else default
37
+
38
+
39
+ class Handler(BaseHTTPRequestHandler):
40
+ server_version = "AATDashboard/0.1"
41
+ protocol_version = "HTTP/1.1"
42
+
43
+ # ---- low-level response helpers -------------------------------------
44
+ def _send_json(self, obj, status: int = 200):
45
+ payload = json.dumps(obj, ensure_ascii=False, default=str).encode("utf-8")
46
+ self.send_response(status)
47
+ self.send_header("Content-Type", "application/json; charset=utf-8")
48
+ self.send_header("Content-Length", str(len(payload)))
49
+ self.send_header("Cache-Control", "no-store")
50
+ self.end_headers()
51
+ self.wfile.write(payload)
52
+
53
+ def _send_bytes(self, data: bytes, ctype: str, status: int = 200):
54
+ self.send_response(status)
55
+ self.send_header("Content-Type", ctype)
56
+ self.send_header("Content-Length", str(len(data)))
57
+ self.send_header("Cache-Control", "no-store") # local tool - always fresh
58
+ self.end_headers()
59
+ self.wfile.write(data)
60
+
61
+ def _sse_open(self):
62
+ self.send_response(200)
63
+ self.send_header("Content-Type", "text/event-stream; charset=utf-8")
64
+ self.send_header("Cache-Control", "no-store")
65
+ self.send_header("Connection", "keep-alive")
66
+ self.end_headers()
67
+
68
+ def _sse_send(self, event: str, data: dict):
69
+ chunk = f"event: {event}\ndata: {json.dumps(data, default=str)}\n\n"
70
+ self.wfile.write(chunk.encode("utf-8"))
71
+ self.wfile.flush()
72
+
73
+ # ---- auth -----------------------------------------------------------
74
+ def _authed(self, query: dict) -> bool:
75
+ tok = self.headers.get("X-Dashboard-Token")
76
+ if not tok:
77
+ q = query.get("token")
78
+ tok = q[0] if isinstance(q, list) and q else None
79
+ return security.token_ok(tok)
80
+
81
+ # ---- static ---------------------------------------------------------
82
+ def _serve_static(self, path: str):
83
+ rel = "index.html" if path in ("/", "") else path.lstrip("/")
84
+ if rel.startswith("static/"):
85
+ rel = rel[len("static/"):]
86
+ target = (WEB_DIR / rel).resolve()
87
+ if WEB_DIR.resolve() not in target.parents and target != WEB_DIR.resolve():
88
+ self._send_json({"error": "forbidden"}, 403)
89
+ return
90
+ if not target.is_file():
91
+ self._send_json({"error": "not found", "path": path}, 404)
92
+ return
93
+ ctype = _CTYPES.get(target.suffix, "application/octet-stream")
94
+ self._send_bytes(target.read_bytes(), ctype)
95
+
96
+ # ---- dispatch -------------------------------------------------------
97
+ def do_GET(self):
98
+ parsed = urlparse(self.path)
99
+ path, query = parsed.path, parse_qs(parsed.query)
100
+ if not path.startswith("/api/"):
101
+ return self._serve_static(path)
102
+ if not self._authed(query):
103
+ return self._send_json({"error": "unauthorized"}, 401)
104
+ if path == "/api/validate/all":
105
+ return self._route_sse(Req("GET", path, query, None))
106
+ return self._route(Req("GET", path, query, None))
107
+
108
+ def do_POST(self):
109
+ parsed = urlparse(self.path)
110
+ path, query = parsed.path, parse_qs(parsed.query)
111
+ if not self._authed(query):
112
+ return self._send_json({"error": "unauthorized"}, 401)
113
+ body = self._read_body()
114
+ return self._route(Req("POST", path, query, body))
115
+
116
+ def _read_body(self) -> dict | None:
117
+ length = int(self.headers.get("Content-Length") or 0)
118
+ if not length:
119
+ return None
120
+ raw = self.rfile.read(length)
121
+ try:
122
+ return json.loads(raw.decode("utf-8"))
123
+ except (ValueError, UnicodeDecodeError):
124
+ return None
125
+
126
+ def _route(self, req: Req):
127
+ try:
128
+ from . import routes
129
+ fn = routes.resolve(req.method, req.path)
130
+ if fn is None:
131
+ return self._send_json({"error": "no such route",
132
+ "path": req.path}, 404)
133
+ result = fn(req)
134
+ if isinstance(result, tuple):
135
+ status, obj = result
136
+ return self._send_json(obj, status)
137
+ return self._send_json(result)
138
+ except Exception as e: # noqa: BLE001 - surface as JSON, never 500-crash
139
+ return self._send_json(
140
+ {"error": "handler_exception", "message": str(e),
141
+ "trace": traceback.format_exc().splitlines()[-6:]}, 500)
142
+
143
+ def _route_sse(self, req: Req):
144
+ try:
145
+ from . import validate
146
+ self._sse_open()
147
+ for event, data in validate.stream_all(req):
148
+ self._sse_send(event, data)
149
+ self._sse_send("done", {"ok": True})
150
+ except BrokenPipeError:
151
+ pass
152
+ except Exception as e: # noqa: BLE001
153
+ try:
154
+ self._sse_send("error", {"message": str(e)})
155
+ except Exception:
156
+ pass
157
+
158
+ def log_message(self, fmt, *args):
159
+ # Quiet by default; the launcher prints a startup banner instead.
160
+ pass
@@ -0,0 +1,213 @@
1
+ """The read model: assemble the full dashboard picture from the live registry.
2
+
3
+ Reads are in-process (import registry / userdata / bootstraplib) so the inventory
4
+ is fast and always reflects the real folder + Credential Manager state. The only
5
+ subprocess reads here are the store stats and llm providers (they belong to tools
6
+ that own their own config/DB).
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import sqlite3
12
+ import threading
13
+ import time
14
+ from typing import Any
15
+
16
+ import registry
17
+ from agents.orchestrator import bootstraplib
18
+ from tools._lib import creds, userdata
19
+
20
+ # A full build scans every manifest (a few seconds on a large registry). Cache it
21
+ # briefly and serialize builds so a page reload, a validation reconnect, or two
22
+ # concurrent requests never stack N full scans. Mutations (credential/config
23
+ # writes) call invalidate() so the next read reflects the change immediately.
24
+ _INV_TTL = 4.0
25
+ _INV_LOCK = threading.Lock()
26
+ _INV_CACHE: dict[str, Any] = {"ts": 0.0, "data": None}
27
+
28
+
29
+ def invalidate() -> None:
30
+ with _INV_LOCK:
31
+ _INV_CACHE["ts"] = 0.0
32
+ _INV_CACHE["data"] = None
33
+
34
+
35
+ def _probe_kind(entry: dict[str, Any]) -> str | None:
36
+ """What live-validation path exists for this capability: an explicit
37
+ healthcheck, else a conventional auth-status action, else nothing."""
38
+ if entry.get("healthcheck"):
39
+ return "healthcheck"
40
+ action_names = {a["name"] for a in entry.get("actions", [])}
41
+ if "auth-status" in action_names:
42
+ return "auth-status"
43
+ return None
44
+
45
+
46
+ def _present_sessions() -> set[str]:
47
+ """Base names of saved web sessions (X.json / X.profile / X.cookies.json)."""
48
+ d = userdata.sessions_dir()
49
+ names: set[str] = set()
50
+ if not d.exists():
51
+ return names
52
+ for p in d.iterdir():
53
+ for suf in (".cookies.json", ".json", ".profile"):
54
+ if p.name.endswith(suf):
55
+ names.add(p.name[: -len(suf)])
56
+ break
57
+ return names
58
+
59
+
60
+ def _annotate(entry: dict[str, Any], kind: str,
61
+ present_sessions: set[str] | None = None) -> dict[str, Any]:
62
+ entry["kind"] = kind
63
+ missing = set(entry.get("missing_secrets", []))
64
+ # OAuth tools carry oauth-token/oauth-accounts secrets that are PRODUCED by the
65
+ # sign-in flow (auth-login), not entered by hand. Hide them from the card so a
66
+ # newcomer sees "Connect (sign in)" instead of confusing set/delete rows for a
67
+ # token they can't type. The oauth CLIENT key (which the user does provide) stays.
68
+ has_oauth = any(a.get("name") == "auth-login" for a in entry.get("actions", []))
69
+
70
+ def _oauth_output(nm: str) -> bool:
71
+ return has_oauth and (nm.endswith("oauth-token") or nm.endswith("oauth-accounts"))
72
+
73
+ entry["secrets_status"] = [
74
+ {"name": s["name"], "description": s.get("description", ""),
75
+ "present": s["name"] not in missing}
76
+ for s in entry.get("secrets", []) if not _oauth_output(s["name"])
77
+ ]
78
+ entry["probe"] = _probe_kind(entry)
79
+ # A tool may need a saved web login instead of (or on top of) a credential.
80
+ ws = entry.get("web_session")
81
+ session_missing = False
82
+ if ws:
83
+ present = ws["name"] in (present_sessions or set())
84
+ entry["web_session_status"] = {
85
+ "name": ws["name"], "login_url": ws.get("login_url", ""),
86
+ "persistent": ws.get("persistent", False), "channel": ws.get("channel", ""),
87
+ "label": ws.get("label", ""), "present": present}
88
+ session_missing = not present
89
+ entry["needs_setup"] = bool(missing) or session_missing or (
90
+ kind == "agent" and not entry.get("ready", False))
91
+ return entry
92
+
93
+
94
+ def store_stats() -> dict[str, Any] | None:
95
+ """Record/run counts read straight from the SQLite store (read-only), so the
96
+ dashboard never shells out to the context-store tool for a simple count -
97
+ faster, and immune to the keyring-import hang that afflicts subprocesses
98
+ spawned from a detached parent."""
99
+ p = userdata.store_db_path()
100
+ if not p.exists():
101
+ return None
102
+ try:
103
+ con = sqlite3.connect(f"file:{p}?mode=ro", uri=True, timeout=5)
104
+ except sqlite3.Error:
105
+ return None
106
+ try:
107
+ rec = con.execute("SELECT count(*) FROM records").fetchone()[0]
108
+ runs = con.execute("SELECT count(*) FROM runs").fetchone()[0]
109
+ openruns = con.execute(
110
+ "SELECT count(*) FROM runs WHERE status IN ('open','active')").fetchone()[0]
111
+ return {"records": rec, "runs": runs, "open_runs": openruns}
112
+ except sqlite3.Error:
113
+ return None # schema not initialized yet (fresh install)
114
+ finally:
115
+ con.close()
116
+
117
+
118
+ def providers() -> dict[str, Any]:
119
+ """llm provider config + key presence (NEVER a key value), read in-process
120
+ from providers.json + Credential Manager. Mirrors the llm tool's
121
+ list-providers shape without importing that tool's provider adapters (which
122
+ require its own sys.path) or spawning a subprocess."""
123
+ p = userdata.config_dir("llm") / "providers.json"
124
+ if not p.exists():
125
+ return {"default": None, "providers": [],
126
+ "error": {"code": "no_config", "message": "no providers.json yet"}}
127
+ try:
128
+ cfg = json.loads(p.read_text(encoding="utf-8"))
129
+ except ValueError as e:
130
+ return {"default": None, "providers": [],
131
+ "error": {"code": "bad_config", "message": str(e)}}
132
+ default = cfg.get("default")
133
+ out = []
134
+ for name, pc in (cfg.get("providers") or {}).items():
135
+ out.append({
136
+ "name": name,
137
+ "adapter": pc.get("adapter", "openai_compat"),
138
+ "base_url": pc.get("base_url"),
139
+ "model": pc.get("model"),
140
+ "auth_style": pc.get("auth_style", "bearer"),
141
+ "config": {k: v for k, v in pc.items() if k != "api_key"},
142
+ "key_present": creds.has_for_report("llm", name),
143
+ "is_default": name == default,
144
+ })
145
+ return {"default": default, "providers": out}
146
+
147
+
148
+ def build(force: bool = False) -> dict[str, Any]:
149
+ """Cached, single-flight inventory build."""
150
+ with _INV_LOCK:
151
+ fresh = (_INV_CACHE["data"] is not None
152
+ and (time.time() - _INV_CACHE["ts"]) < _INV_TTL)
153
+ if fresh and not force:
154
+ return _INV_CACHE["data"]
155
+ data = _build()
156
+ _INV_CACHE["ts"] = time.time()
157
+ _INV_CACHE["data"] = data
158
+ return data
159
+
160
+
161
+ def _build() -> dict[str, Any]:
162
+ tool_entries = registry.list_tools()
163
+ tool_index = {t["name"]: t for t in tool_entries}
164
+ sessions = _present_sessions()
165
+ tools = [_annotate(t, "tool", sessions) for t in tool_entries]
166
+ agents = [_annotate(a, "agent", sessions)
167
+ for a in registry.list_agents(tool_index=tool_index)]
168
+ skills = registry.list_skills()
169
+ for s in skills:
170
+ s["kind"] = "skill"
171
+
172
+ store = store_stats()
173
+ fresh = bootstraplib.freshness(store)
174
+ prov = providers()
175
+ llm_ready = any(p.get("key_present") for p in prov.get("providers", []))
176
+
177
+ def cnt(items, pred):
178
+ return sum(1 for x in items if pred(x))
179
+
180
+ def is_ready(x): # truly set up: no missing secrets, no missing session, loads
181
+ return not x.get("needs_setup") and not x.get("error")
182
+
183
+ summary = {
184
+ "tools": {
185
+ "total": len(tools),
186
+ "ready": cnt(tools, is_ready),
187
+ "needs_setup": cnt(tools, lambda t: t.get("needs_setup")),
188
+ "errored": cnt(tools, lambda t: t.get("error")),
189
+ },
190
+ "agents": {
191
+ "total": len(agents),
192
+ "ready": cnt(agents, is_ready),
193
+ "needs_setup": cnt(agents, lambda a: a.get("needs_setup")),
194
+ "errored": cnt(agents, lambda a: a.get("error")),
195
+ },
196
+ "skills": {"total": len(skills)},
197
+ "llm_ready": llm_ready,
198
+ }
199
+
200
+ return {
201
+ "summary": summary,
202
+ "tools": tools,
203
+ "agents": agents,
204
+ "skills": skills,
205
+ "providers": prov,
206
+ "store": store,
207
+ "userdata": {
208
+ **userdata.describe(),
209
+ "scan": fresh["scan"],
210
+ },
211
+ "fresh_start": fresh["fresh_start"],
212
+ "onboarding": bootstraplib.onboarding_hint() if fresh["fresh_start"] else None,
213
+ }
@@ -0,0 +1,118 @@
1
+ """Background jobs for interactive setup steps that outlive one request.
2
+
3
+ Two shapes:
4
+ * a plain job that runs a script to completion and streams its output
5
+ (OAuth login: the tool opens a browser and self-completes on the localhost
6
+ redirect), and
7
+ * a signal job that launches a script which blocks for a stdin ENTER
8
+ (web save-session: a headed browser opens, the human logs in, then the UI
9
+ sends the signal to persist the session).
10
+
11
+ Jobs live in memory only. The dashboard is single-user and local; a restart just
12
+ drops in-flight logins, which the user re-runs.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import subprocess
17
+ import threading
18
+ import time
19
+ import uuid
20
+ from typing import Any
21
+
22
+ from . import runner
23
+
24
+ _JOBS: dict[str, "Job"] = {}
25
+ _LOCK = threading.Lock()
26
+
27
+
28
+ class Job:
29
+ def __init__(self, kind: str, argv: list[str], *, stdin_signal: bool):
30
+ self.id = uuid.uuid4().hex[:12]
31
+ self.kind = kind
32
+ self.argv = argv
33
+ self.stdin_signal = stdin_signal
34
+ self.status = "starting" # starting|awaiting_signal|running|done|failed
35
+ self.logs: list[str] = []
36
+ self.result: dict | None = None
37
+ self.error: str | None = None
38
+ self.created = time.time()
39
+ self._proc: subprocess.Popen | None = None
40
+ self._lock = threading.Lock()
41
+
42
+ def _log(self, line: str):
43
+ with self._lock:
44
+ self.logs.append(line.rstrip("\n"))
45
+ if len(self.logs) > 400:
46
+ self.logs = self.logs[-400:]
47
+
48
+ def start(self):
49
+ cmd = [runner.python_exe(), str(runner.PROJECT_ROOT / "scripts" / self.argv[0]),
50
+ *self.argv[1:]]
51
+ try:
52
+ self._proc = subprocess.Popen(
53
+ cmd, cwd=str(runner.PROJECT_ROOT), text=True, encoding="utf-8",
54
+ errors="replace", bufsize=1,
55
+ stdin=subprocess.PIPE if self.stdin_signal else subprocess.DEVNULL,
56
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
57
+ except Exception as e: # noqa: BLE001
58
+ self.status = "failed"
59
+ self.error = f"could not launch: {e}"
60
+ return
61
+ self.status = "awaiting_signal" if self.stdin_signal else "running"
62
+ threading.Thread(target=self._pump, daemon=True).start()
63
+
64
+ def _pump(self):
65
+ assert self._proc is not None
66
+ for line in self._proc.stdout: # blocks until each line / EOF
67
+ self._log(line)
68
+ self._proc.wait()
69
+ result = runner._parse_json("\n".join(self.logs))
70
+ if self._proc.returncode == 0 and isinstance(result, dict) and "error" not in result:
71
+ self.status = "done"
72
+ self.result = result
73
+ else:
74
+ self.status = "failed"
75
+ if isinstance(result, dict) and "error" in result:
76
+ self.error = result["error"].get("message") if isinstance(
77
+ result["error"], dict) else str(result["error"])
78
+ else:
79
+ self.error = (self.logs[-1] if self.logs else
80
+ f"exited with code {self._proc.returncode}")
81
+
82
+ def signal(self) -> bool:
83
+ """Send the ENTER that a save-session subprocess is blocking on."""
84
+ if not (self._proc and self._proc.stdin and self.status == "awaiting_signal"):
85
+ return False
86
+ try:
87
+ self._proc.stdin.write("\n")
88
+ self._proc.stdin.flush()
89
+ self.status = "running"
90
+ return True
91
+ except Exception: # noqa: BLE001
92
+ return False
93
+
94
+ def wait(self, timeout: float) -> None:
95
+ if self._proc:
96
+ try:
97
+ self._proc.wait(timeout=timeout)
98
+ except subprocess.TimeoutExpired:
99
+ pass
100
+
101
+ def snapshot(self) -> dict[str, Any]:
102
+ with self._lock:
103
+ return {"id": self.id, "kind": self.kind, "status": self.status,
104
+ "logs": list(self.logs[-40:]), "result": self.result,
105
+ "error": self.error}
106
+
107
+
108
+ def create(kind: str, argv: list[str], *, stdin_signal: bool = False) -> Job:
109
+ job = Job(kind, argv, stdin_signal=stdin_signal)
110
+ with _LOCK:
111
+ _JOBS[job.id] = job
112
+ job.start()
113
+ return job
114
+
115
+
116
+ def get(job_id: str) -> Job | None:
117
+ with _LOCK:
118
+ return _JOBS.get(job_id)