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,370 @@
1
+ """Auto-discovery for tools and agents.
2
+
3
+ Walks tools/*/tool.yaml and agents/*/agent.yaml, validates manifests, and
4
+ returns a unified registry. Used by:
5
+ - scripts/list-tools.py and scripts/run-tool.py
6
+ - Agents (when they ship) to introspect available tools without hardcoding.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import os
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ from tools._lib import creds
16
+ from tools._lib.manifest import load_agent, load_skill, load_tool
17
+
18
+ ROOT = Path(__file__).parent
19
+ TOOLS_DIR = ROOT / "tools"
20
+ AGENTS_DIR = ROOT / "agents"
21
+ SKILLS_DIR = ROOT / "skills"
22
+
23
+
24
+ def hidden_tools() -> set[str]:
25
+ """Tool names this session must not see, by directory name.
26
+
27
+ A scoped tool surface. Two sources, env first so a single run can override the
28
+ persisted setting:
29
+
30
+ AAT_TOOLS_HIDE=a,b (env, comma-separated)
31
+ context-state-knowledge/config/registry/hidden-tools.json -> {"hide": [...]}
32
+
33
+ Hiding is REGISTRY-level only: the directory keeps its name and stays a normal
34
+ Python package, so a tool that imports another one directly keeps working, and
35
+ `get_tool(..., respect_hidden=False)` still resolves it for the framework's own
36
+ plumbing. That separation is what let an A/B run swap the surface a session was
37
+ offered without renaming anything or editing the code under test.
38
+
39
+ Never raises: an unreadable config must not take the whole registry down."""
40
+ raw = os.environ.get("AAT_TOOLS_HIDE")
41
+ if raw is not None:
42
+ return {n.strip() for n in raw.split(",") if n.strip()}
43
+ try:
44
+ from tools._lib import userdata
45
+ cfg = Path(userdata.config_dir("registry")) / "hidden-tools.json"
46
+ if cfg.exists():
47
+ data = json.loads(cfg.read_text(encoding="utf-8"))
48
+ return {str(n) for n in data.get("hide", [])}
49
+ except Exception: # noqa: BLE001 - scoping is a convenience, never a blocker
50
+ pass
51
+ return set()
52
+
53
+
54
+ def _has_secret(tool_name: str, secret_name: str) -> bool:
55
+ """Check secret presence. Supports `namespace:name` for shared secrets,
56
+ e.g. `google:oauth-client` -> agents-and-tools:google:oauth-client.
57
+
58
+ Never raises. Readiness is a REPORT, and a machine with no reachable
59
+ credential store still has to be able to list what is installed: a headless
60
+ Linux box has no session keyring at all, so constructing the backend there
61
+ throws and would otherwise take down the whole registry, the router build and
62
+ the dashboard with it. Unreachable is reported the same as absent, which is
63
+ the honest answer to "is this tool ready" - it is not, and the store error
64
+ says why the moment anyone actually calls creds.get, which still raises.
65
+ """
66
+ if ":" in secret_name:
67
+ ns, _, name = secret_name.partition(":")
68
+ return creds.has_for_report(ns, name)
69
+ return creds.has_for_report(tool_name, secret_name)
70
+
71
+
72
+ def _oauth_scope_gap(tool_dir: Path) -> list[str] | None:
73
+ """Scopes a tool declares that the stored OAuth token does not carry.
74
+
75
+ `ready` used to mean only "every declared secret is present". The whole
76
+ google-* family shares one client + one token, so the moment ANY of them
77
+ finished its OAuth flow all of them flipped ready - carrying only the
78
+ scopes that one flow had requested. Seven tools reported ready and then
79
+ answered 403 "insufficient authentication scopes" on first use.
80
+
81
+ Returns None when the tool has no OAuth scope surface at all, so "no gap"
82
+ and "not applicable" stay distinguishable. Never raises: readiness
83
+ reporting must not be able to take the registry down.
84
+ """
85
+ auth_py = tool_dir / "auth.py"
86
+ if not auth_py.exists():
87
+ return None
88
+ try:
89
+ if "register_scopes" not in auth_py.read_text(encoding="utf-8"):
90
+ return None
91
+ import importlib
92
+
93
+ mod = importlib.import_module(f"tools.{tool_dir.name}.auth")
94
+ declared = set(getattr(mod, "SCOPES", None) or [])
95
+ if not declared:
96
+ return None
97
+ from tools._lib import google_auth
98
+
99
+ token = google_auth._load_token()
100
+ if token is None:
101
+ # No token at all is already reported as a missing secret; saying
102
+ # it twice, as ten missing scopes, buries the actual instruction.
103
+ return None
104
+ held = set(token.get("scopes") or [])
105
+ return sorted(declared - held)
106
+ except Exception: # noqa: BLE001 - see docstring
107
+ return None
108
+
109
+
110
+ def list_tools() -> list[dict[str, Any]]:
111
+ out: list[dict[str, Any]] = []
112
+ if not TOOLS_DIR.exists():
113
+ return out
114
+ hidden = hidden_tools()
115
+ for manifest_path in sorted(TOOLS_DIR.glob("*/tool.yaml")):
116
+ dir_name = manifest_path.parent.name
117
+ if dir_name.startswith("_") or dir_name in hidden:
118
+ continue
119
+ try:
120
+ m = load_tool(manifest_path)
121
+ except Exception as e:
122
+ out.append({
123
+ "name": dir_name,
124
+ "error": f"manifest load failed: {e}",
125
+ "ready": False,
126
+ })
127
+ continue
128
+ absent = [s for s in m.secrets if not _has_secret(m.name, s.name)]
129
+ missing = [s.name for s in absent if not s.optional]
130
+ missing_optional = [s.name for s in absent if s.optional]
131
+ missing_scopes = _oauth_scope_gap(manifest_path.parent) or []
132
+ # Three outcomes, one boolean plus a label. `ready` stays a bool so no
133
+ # existing consumer breaks, but "authorized, just not for this tool" is
134
+ # the normal state during incremental setup, not an error - and it
135
+ # needs a different instruction ("re-run auth-login") from a missing
136
+ # credential ("store the secret"), so the label carries which.
137
+ if missing:
138
+ readiness = "needs-credentials"
139
+ elif missing_scopes:
140
+ readiness = "needs-scopes"
141
+ else:
142
+ readiness = "ready"
143
+ out.append({
144
+ "name": m.name,
145
+ "description": m.description,
146
+ "version": m.version,
147
+ "tier": m.tier,
148
+ "path": str(m.path),
149
+ "entrypoint": m.entrypoint,
150
+ "args": [a.model_dump(by_alias=True) for a in m.args],
151
+ "actions": [
152
+ # examples/output_schema ride along when a manifest declares them: they
153
+ # are what makes a structured argument usable without trial and error,
154
+ # and a consumer that only sees name/description/args cannot recover them.
155
+ {
156
+ "name": a.name,
157
+ "description": a.description,
158
+ "args": [arg.model_dump(by_alias=True) for arg in a.args],
159
+ **({"examples": a.examples} if a.examples else {}),
160
+ **({"output_schema": a.output_schema} if a.output_schema else {}),
161
+ }
162
+ for a in m.actions
163
+ ],
164
+ "secrets": [s.model_dump() for s in m.secrets],
165
+ "routing": m.routing.model_dump() if m.routing else None,
166
+ "healthcheck": m.healthcheck.model_dump() if m.healthcheck else None,
167
+ "web_session": m.web_session.model_dump() if m.web_session else None,
168
+ "missing_secrets": missing,
169
+ # Absent but not blocking: shown so setup can still offer them,
170
+ # never counted against readiness.
171
+ "missing_optional_secrets": missing_optional,
172
+ "missing_scopes": missing_scopes,
173
+ "readiness": readiness,
174
+ "ready": readiness == "ready",
175
+ })
176
+ return out
177
+
178
+
179
+ def get_tool(name: str, *, respect_hidden: bool = True):
180
+ """Resolve a tool manifest by name.
181
+
182
+ ``respect_hidden=False`` bypasses the scoped surface. Agents pass it: hiding
183
+ is meant to shrink what a SESSION is offered, not to amputate the framework
184
+ underneath it. Hiding a tool used to disable every agent that drives it -
185
+ `procesio audit` died with "no registered tool named 'procesio'" the moment
186
+ that tool was scoped out for an experiment - which is a silent, confusing
187
+ failure a long way from its cause."""
188
+ import sys
189
+ hidden = hidden_tools() if respect_hidden else set()
190
+ if name in hidden:
191
+ raise KeyError(f"tool not found: {name}")
192
+ for manifest_path in TOOLS_DIR.glob("*/tool.yaml"):
193
+ if manifest_path.parent.name.startswith("_") or manifest_path.parent.name in hidden:
194
+ continue
195
+ try:
196
+ m = load_tool(manifest_path)
197
+ except Exception as exc: # noqa: BLE001
198
+ # A broken/transiently-unreadable SIBLING manifest must not block the
199
+ # requested tool. Re-raise only if it's the tool we were asked for.
200
+ if manifest_path.parent.name == name:
201
+ raise
202
+ print(f"warning: skipping unloadable tool manifest "
203
+ f"'{manifest_path.parent.name}': {exc}", file=sys.stderr)
204
+ continue
205
+ if m.name == name:
206
+ return m
207
+ raise KeyError(f"tool not found: {name}")
208
+
209
+
210
+ def list_agents(tool_index: dict[str, dict] | None = None) -> list[dict[str, Any]]:
211
+ out: list[dict[str, Any]] = []
212
+ if not AGENTS_DIR.exists():
213
+ return out
214
+ # Index every tool ONCE (name -> its list_tools() entry, which already carries
215
+ # ready/missing_secrets). Previously each driven-tool lookup called get_tool(),
216
+ # which re-globbed and re-parsed all tool manifests - O(agents x tools) YAML
217
+ # parses that made this call take tens of seconds on a large registry. A caller
218
+ # that has already built the tool list (e.g. the dashboard) can pass it in to
219
+ # avoid a second full scan.
220
+ if tool_index is None:
221
+ tool_index = {t["name"]: t for t in list_tools()}
222
+ for manifest_path in sorted(AGENTS_DIR.glob("*/agent.yaml")):
223
+ dir_name = manifest_path.parent.name
224
+ if dir_name.startswith("_"):
225
+ continue
226
+ try:
227
+ m = load_agent(manifest_path)
228
+ except Exception as e:
229
+ out.append({"name": dir_name, "error": str(e), "ready": False})
230
+ continue
231
+ missing = [s.name for s in m.secrets if not _has_secret(m.name, s.name)]
232
+ # An agent is "ready" only if its own secrets AND every tool it drives
233
+ # are present and ready. Surface unready tools so gaps are visible.
234
+ tool_status = {}
235
+ for tname in m.tools:
236
+ t = tool_index.get(tname)
237
+ if t is not None and not t.get("error"):
238
+ tool_status[tname] = {"present": True, "ready": bool(t.get("ready")),
239
+ "missing_secrets": t.get("missing_secrets", [])}
240
+ else:
241
+ tool_status[tname] = {"present": False, "ready": False,
242
+ "missing_secrets": []}
243
+ out.append({
244
+ "name": m.name,
245
+ "description": m.description,
246
+ "version": m.version,
247
+ "tier": m.tier,
248
+ "path": str(m.path),
249
+ "entrypoint": m.entrypoint,
250
+ "tools": m.tools,
251
+ "tool_status": tool_status,
252
+ "actions": [
253
+ {"name": a.name, "description": a.description,
254
+ "args": [arg.model_dump(by_alias=True) for arg in a.args],
255
+ **({"examples": a.examples} if a.examples else {}),
256
+ **({"output_schema": a.output_schema} if a.output_schema else {})}
257
+ for a in m.actions
258
+ ],
259
+ "secrets": [s.model_dump() for s in m.secrets],
260
+ "routing": m.routing.model_dump() if m.routing else None,
261
+ "healthcheck": m.healthcheck.model_dump() if m.healthcheck else None,
262
+ "missing_secrets": missing,
263
+ # An agent is ready only when its own secrets AND every tool it drives
264
+ # are ready (matches the docstring above). own_ready is surfaced too so
265
+ # a UI can distinguish "agent's own creds are set" from "a driven tool
266
+ # is missing creds".
267
+ "own_ready": len(missing) == 0,
268
+ "ready": len(missing) == 0 and all(
269
+ st["ready"] for st in tool_status.values()),
270
+ })
271
+ return out
272
+
273
+
274
+ def get_agent(name: str):
275
+ for manifest_path in AGENTS_DIR.glob("*/agent.yaml"):
276
+ if manifest_path.parent.name.startswith("_"):
277
+ continue
278
+ m = load_agent(manifest_path)
279
+ if m.name == name:
280
+ return m
281
+ raise KeyError(f"agent not found: {name}")
282
+
283
+
284
+ def list_skills() -> list[dict[str, Any]]:
285
+ """Discover skills. A skill's `SKILL.md` frontmatter is its manifest; skills
286
+ carry no secrets, so a successfully-loaded skill is always ready."""
287
+ out: list[dict[str, Any]] = []
288
+ if not SKILLS_DIR.exists():
289
+ return out
290
+ for skill_md in sorted(SKILLS_DIR.glob("*/SKILL.md")):
291
+ dir_name = skill_md.parent.name
292
+ if dir_name.startswith("_") or dir_name == "tests":
293
+ continue
294
+ try:
295
+ m = load_skill(skill_md)
296
+ except Exception as e:
297
+ out.append({
298
+ "name": dir_name,
299
+ "error": f"manifest load failed: {e}",
300
+ "ready": False,
301
+ })
302
+ continue
303
+ entry = {
304
+ "name": m.name,
305
+ "description": m.description,
306
+ "version": m.version,
307
+ "path": str(m.path),
308
+ "routing": m.routing.model_dump() if m.routing else None,
309
+ "ready": True,
310
+ }
311
+ # Non-fatal hygiene signal: folder name should match the manifest name.
312
+ if m.name != dir_name:
313
+ entry["warning"] = f"folder '{dir_name}' != skill name '{m.name}'"
314
+ out.append(entry)
315
+ return out
316
+
317
+
318
+ def get_skill(name: str):
319
+ for skill_md in SKILLS_DIR.glob("*/SKILL.md"):
320
+ if skill_md.parent.name.startswith("_") or skill_md.parent.name == "tests":
321
+ continue
322
+ m = load_skill(skill_md)
323
+ if m.name == name:
324
+ return m
325
+ raise KeyError(f"skill not found: {name}")
326
+
327
+
328
+ def resolve_catalog(entries: list[dict[str, Any]],
329
+ ws_overrides: dict[str, dict] | None = None) -> list[dict[str, Any]]:
330
+ """Effective per-workspace catalog under the official/template/custom + copy-on-write
331
+ model (spec P0.0-06 / D11). Pure function over registry entries + a per-workspace
332
+ override map (name -> the workspace's own copy/custom); the override STORE is the
333
+ platform's job (object storage / a package feed), so this stays testable and
334
+ storage-agnostic.
335
+
336
+ Rules:
337
+ - official : always present, from the shared registry; a workspace CANNOT override
338
+ it (users can't change official).
339
+ - template : the workspace's override if it forked one (copy-on-write), else the
340
+ shared template. An untouched workspace holds ZERO copies (conserve resources).
341
+ - custom : the workspace's own entries (overrides that don't shadow an official).
342
+
343
+ Each returned entry carries `effective_tier` in
344
+ {official, template, custom-copy, custom}. `ws_overrides` unset = the shared catalog
345
+ unchanged (exactly the single-tenant local behaviour)."""
346
+ ws_overrides = dict(ws_overrides or {})
347
+ by_name = {e["name"]: e for e in entries}
348
+ out: dict[str, dict] = {}
349
+
350
+ for e in entries:
351
+ tier = e.get("tier", "template")
352
+ if tier == "official":
353
+ out[e["name"]] = {**e, "effective_tier": "official"}
354
+ elif tier == "template":
355
+ if e["name"] in ws_overrides:
356
+ out[e["name"]] = {**ws_overrides[e["name"]],
357
+ "name": e["name"], "effective_tier": "custom-copy"}
358
+ else:
359
+ out[e["name"]] = {**e, "effective_tier": "template"}
360
+ # a 'custom'-tier entry shipped in the base registry is unusual; customs are
361
+ # expected to arrive via ws_overrides, handled below.
362
+
363
+ for name, ov in ws_overrides.items():
364
+ base = by_name.get(name)
365
+ if base is not None and base.get("tier") == "official":
366
+ continue # official is immutable per-workspace
367
+ if name not in out:
368
+ out[name] = {**ov, "name": name, "effective_tier": "custom"}
369
+
370
+ return list(out.values())
@@ -0,0 +1,249 @@
1
+ """Generate the Capability Router block inside CLAUDE.md from the registry.
2
+
3
+ The router is a compact request->tool/agent map that auto-loads every session
4
+ (because CLAUDE.md is injected as project instructions). It lets a request be
5
+ matched to the right tool with zero discovery steps.
6
+
7
+ Source of truth is the registry (manifests). A tool can curate its own routing
8
+ via a `routing:` block in tool.yaml (triggers / primary_action / example); when
9
+ absent, this script falls back to the description and a heuristic primary action.
10
+
11
+ The block is a pure function of the manifests. Nothing machine-specific goes in
12
+ it - notably NOT which credentials the generating machine happens to hold, which
13
+ used to land here and made the committed CLAUDE.md differ per person (so the
14
+ sync test could only pass for whoever regenerated last). Live readiness belongs
15
+ to `list-tools.py` and the dashboard; here it is a stderr warning.
16
+
17
+ Usage:
18
+ python scripts/build-router.py # rewrite the block in CLAUDE.md
19
+ python scripts/build-router.py --print # print the block to stdout, write nothing
20
+ python scripts/build-router.py --check # exit 1 if CLAUDE.md is out of date (CI guard)
21
+ """
22
+ from __future__ import annotations
23
+
24
+ import argparse
25
+ import sys
26
+ from pathlib import Path
27
+
28
+ # Auto-switch to the project's .venv Python if launched with a different one.
29
+ _PROJECT_ROOT = Path(__file__).resolve().parents[1]
30
+ # .venv layout is per-OS: Scripts/python.exe on Windows, bin/python everywhere
31
+ # else. Hardcoding the Windows path made this a silent no-op on macOS/Linux,
32
+ # where the script then ran on whatever interpreter happened to invoke it.
33
+ _VENV_PY = (_PROJECT_ROOT / ".venv" / "Scripts" / "python.exe" if sys.platform == "win32"
34
+ else _PROJECT_ROOT / ".venv" / "bin" / "python")
35
+ if _VENV_PY.exists() and Path(sys.executable).resolve() != _VENV_PY.resolve():
36
+ import subprocess
37
+ sys.exit(subprocess.run([str(_VENV_PY), __file__, *sys.argv[1:]]).returncode)
38
+
39
+ try:
40
+ sys.stdout.reconfigure(encoding="utf-8")
41
+ except (AttributeError, ValueError):
42
+ pass
43
+
44
+ sys.path.insert(0, str(_PROJECT_ROOT))
45
+
46
+ from registry import list_agents, list_skills, list_tools # noqa: E402
47
+
48
+ START = "<!-- CAPABILITY-ROUTER:START — generated by scripts/build-router.py; rerun after adding/removing a tool. Do not hand-edit. -->"
49
+ END = "<!-- CAPABILITY-ROUTER:END -->"
50
+
51
+ # Actions that never make a good "first thing to reach for".
52
+ _AUTH_ACTIONS = {"auth-status", "auth-login", "auth-logout", "login", "auth", "web-login", "web-status"}
53
+
54
+ # Skills registered in this project (skills/<name>/) are generated from the
55
+ # registry below. This residual pointer covers harness-only skills that auto-
56
+ # trigger but are NOT bundled in this repo, so the router still routes to them.
57
+ # Keep terse. When a skill here gets imported into skills/, drop its line.
58
+ _HARNESS_SKILLS_POINTER = globals().get("_HARNESS_SKILLS_POINTER", [])
59
+
60
+
61
+ def _first_sentence(text: str, cap: int = 110) -> str:
62
+ text = " ".join((text or "").split())
63
+ for sep in (". ", " — ", "; "):
64
+ if sep in text:
65
+ text = text.split(sep, 1)[0]
66
+ break
67
+ return (text[: cap - 1] + "…") if len(text) > cap else text
68
+
69
+
70
+ def _primary_action(entry: dict) -> str:
71
+ routing = entry.get("routing") or {}
72
+ if routing.get("primary_action"):
73
+ return routing["primary_action"]
74
+ actions = [a["name"] for a in entry.get("actions", [])]
75
+ non_auth = [a for a in actions if a not in _AUTH_ACTIONS]
76
+ return (non_auth or actions or [""])[0]
77
+
78
+
79
+ def _trigger(entry: dict) -> str:
80
+ routing = entry.get("routing") or {}
81
+ if routing.get("triggers"):
82
+ return "; ".join(routing["triggers"])
83
+ return _first_sentence(entry.get("description", ""))
84
+
85
+
86
+ def _example(entry: dict, runner: str) -> str:
87
+ routing = entry.get("routing") or {}
88
+ if routing.get("example"):
89
+ return routing["example"]
90
+ action = _primary_action(entry)
91
+ return f"{entry['name']} {action}".strip()
92
+
93
+
94
+ def _line(entry: dict, runner: str) -> str:
95
+ return f"- **{entry['name']}** — {_trigger(entry)} → `{_example(entry, runner)}`"
96
+
97
+
98
+ def _skill_line(entry: dict) -> str:
99
+ return f"- **{entry['name']}** — {_trigger(entry)} → `get-skill.py {entry['name']}`"
100
+
101
+
102
+ def build_block() -> tuple[str, list[str]]:
103
+ """Return (markdown_block, warnings)."""
104
+ warnings: list[str] = []
105
+ tools = list_tools()
106
+ agents = list_agents()
107
+
108
+ # Listed by MANIFEST validity, not by local credential state. Filtering the
109
+ # listing on `ready` was the same per-machine leak as the readiness line
110
+ # below, only larger: a checkout that had not stored a tool's secret yet
111
+ # silently dropped that tool from the router, so the agent stopped routing
112
+ # to a capability that exists - and the committed file differed per person.
113
+ # Whether YOU can run it is a live question (list-tools.py, the dashboard);
114
+ # whether it EXISTS is a manifest question, and only that belongs here.
115
+ listed = [t for t in tools if "error" not in t]
116
+ not_ready = [t for t in tools if not t.get("ready") and "error" not in t]
117
+ errored = [t for t in tools if "error" in t]
118
+
119
+ for t in listed:
120
+ if not t.get("routing"):
121
+ warnings.append(f"tool '{t['name']}' has no curated routing: block (using description fallback)")
122
+
123
+ lines = [START, ""]
124
+ lines.append("### Tools — run with `python scripts/run-tool.py <tool> <action> [--args]`")
125
+ lines.append("")
126
+ for t in sorted(listed, key=lambda x: x["name"]):
127
+ lines.append(_line(t, "run-tool.py"))
128
+ lines.append("")
129
+
130
+ # Deliberately NOT written into the block: which secrets are stored is a
131
+ # property of one machine, and CLAUDE.md is version-controlled and shared
132
+ # by two teams. Emitting it here made the generated file differ per person,
133
+ # so the sync test could only pass on whoever committed last, and it put
134
+ # user-specific data in a framework file the same document forbids it in.
135
+ # The live answer belongs to `list-tools.py` and the dashboard; here it is
136
+ # a stderr warning, so the information survives without being published.
137
+ for t in sorted(not_ready, key=lambda x: x["name"]):
138
+ miss = ",".join(t.get("missing_secrets", [])) or "credentials"
139
+ warnings.append(f"tool '{t['name']}' needs credentials on this machine ({miss}) - not written to CLAUDE.md")
140
+
141
+ if errored:
142
+ bits = [t["name"] for t in errored]
143
+ lines.append(f"❌ **Manifest errors** (fix before use): {', '.join(bits)}")
144
+ lines.append("")
145
+
146
+ if agents:
147
+ lines.append("### Agents — run with `python scripts/run-agent.py <agent> <action> [--args]`")
148
+ lines.append("")
149
+ for a in sorted(agents, key=lambda x: x["name"]):
150
+ if "error" in a:
151
+ continue
152
+ lines.append(_line(a, "run-agent.py"))
153
+ lines.append("")
154
+
155
+ skills = list_skills()
156
+ skills_ready = [s for s in skills if "error" not in s]
157
+ skills_errored = [s for s in skills if "error" in s]
158
+
159
+ if skills or _HARNESS_SKILLS_POINTER:
160
+ lines.append("### Skills")
161
+ lines.append("")
162
+ lines.append(
163
+ "Claude **auto-triggers** these from their descriptions — do NOT run-tool them. "
164
+ "Project agents discover them via the registry and load one's full content with "
165
+ "`python scripts/get-skill.py <name> --content`."
166
+ )
167
+ lines.append("")
168
+
169
+ if skills:
170
+ lines.append("**Registered in this project** — run `python scripts/list-skills.py` (`skills/<name>/`):")
171
+ lines.append("")
172
+ for s in sorted(skills_ready, key=lambda x: x["name"]):
173
+ lines.append(_skill_line(s))
174
+ if not s.get("routing"):
175
+ warnings.append(f"skill '{s['name']}' has no curated routing: block (using description fallback)")
176
+ lines.append("")
177
+ if skills_errored:
178
+ bits = [s["name"] for s in skills_errored]
179
+ lines.append(f"❌ **Skill manifest errors** (fix before use): {', '.join(bits)}")
180
+ lines.append("")
181
+
182
+ if _HARNESS_SKILLS_POINTER:
183
+ lines.append("**Other harness skills** (auto-trigger; not bundled in this repo):")
184
+ lines.append("")
185
+ for s in _HARNESS_SKILLS_POINTER:
186
+ lines.append(f"- {s}")
187
+ lines.append("")
188
+ lines.append(END)
189
+ return "\n".join(lines), warnings
190
+
191
+
192
+ def splice(claude_md: str, block: str) -> str:
193
+ if START in claude_md and END in claude_md:
194
+ pre = claude_md.split(START, 1)[0].rstrip("\n")
195
+ post = claude_md.split(END, 1)[1].lstrip("\n")
196
+ return f"{pre}\n\n{block}\n\n{post}".rstrip() + "\n"
197
+ # No markers yet: append a section at the end.
198
+ return claude_md.rstrip() + "\n\n## Capability Router (auto-generated)\n\n" + block + "\n"
199
+
200
+
201
+ def main() -> int:
202
+ # argparse, not `in sys.argv`: without it the no-argument path IS the
203
+ # destructive one, so `build-router.py --help` rewrote CLAUDE.md instead of
204
+ # explaining itself - a surprising way to dirty a clean working copy.
205
+ parser = argparse.ArgumentParser(
206
+ description="Regenerate the Capability Router block in CLAUDE.md from the "
207
+ "tool and agent manifests. With no flags it REWRITES CLAUDE.md.",
208
+ epilog="The block is a pure function of the manifests: it carries no "
209
+ "per-machine state, so every checkout generates the same bytes.",
210
+ )
211
+ group = parser.add_mutually_exclusive_group()
212
+ group.add_argument("--print", action="store_true",
213
+ help="Write the block to stdout and change nothing.")
214
+ group.add_argument("--check", action="store_true",
215
+ help="Exit 1 if CLAUDE.md is out of date. Changes nothing.")
216
+ args = parser.parse_args()
217
+
218
+ block, warnings = build_block()
219
+ claude_path = _PROJECT_ROOT / "CLAUDE.md"
220
+
221
+ if args.print:
222
+ print(block)
223
+ for w in warnings:
224
+ print(f"warning: {w}", file=sys.stderr)
225
+ return 0
226
+
227
+ current = claude_path.read_text(encoding="utf-8") if claude_path.exists() else ""
228
+ updated = splice(current, block)
229
+
230
+ if args.check:
231
+ if current != updated:
232
+ print("CLAUDE.md Capability Router is out of date — run scripts/build-router.py", file=sys.stderr)
233
+ return 1
234
+ print("CLAUDE.md Capability Router is up to date.")
235
+ return 0
236
+
237
+ # newline="\n" because on Windows write_text() would translate every \n to \r\n.
238
+ # CLAUDE.md is LF in version control, so without this each run rewrites all ~370
239
+ # lines and buries a real two-line change in a whole-file diff - which the git<->svn
240
+ # mirror then has to resolve line by line. Same reason build-tool-skill.py does it.
241
+ claude_path.write_text(updated, encoding="utf-8", newline="\n")
242
+ print(f"Wrote Capability Router to {claude_path} ({len(updated)} bytes).")
243
+ for w in warnings:
244
+ print(f"warning: {w}", file=sys.stderr)
245
+ return 0
246
+
247
+
248
+ if __name__ == "__main__":
249
+ raise SystemExit(main())