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,54 @@
1
+ """JSON I/O contract for tools.
2
+
3
+ Success: emit({...}) -> one JSON object to stdout, exit 0
4
+ Failure: fail("code", "msg") -> error envelope to stdout, non-zero exit
5
+ Logs: log(...) -> stderr only (never pollutes stdout)
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import sys
11
+ from typing import Any, NoReturn
12
+
13
+ # Windows terminals default to cp1252. Force UTF-8 so tools can emit
14
+ # non-ASCII (Ryver messages, calendar titles, names) without mojibake.
15
+ try:
16
+ sys.stdout.reconfigure(encoding="utf-8")
17
+ sys.stderr.reconfigure(encoding="utf-8")
18
+ except (AttributeError, ValueError):
19
+ pass
20
+
21
+
22
+ def emit(data: dict[str, Any]) -> NoReturn:
23
+ """Print one JSON object to stdout and exit 0."""
24
+ json.dump(data, sys.stdout, ensure_ascii=False)
25
+ sys.stdout.write("\n")
26
+ sys.stdout.flush()
27
+ sys.exit(0)
28
+
29
+
30
+ def fail(
31
+ code: str,
32
+ message: str,
33
+ details: dict[str, Any] | None = None,
34
+ exit_code: int = 1,
35
+ ) -> NoReturn:
36
+ """Print error envelope to stdout and exit non-zero."""
37
+ json.dump(
38
+ {"error": {"code": code, "message": message, "details": details or {}}},
39
+ sys.stdout,
40
+ ensure_ascii=False,
41
+ )
42
+ sys.stdout.write("\n")
43
+ sys.stdout.flush()
44
+ sys.exit(exit_code)
45
+
46
+
47
+ def log(*args: Any) -> None:
48
+ """Write to stderr. Use for progress, debug, anything non-JSON."""
49
+ print(*args, file=sys.stderr, flush=True)
50
+
51
+
52
+ def read_stdin_json() -> dict[str, Any]:
53
+ """For tools that accept JSON on stdin instead of CLI args."""
54
+ return json.load(sys.stdin)
@@ -0,0 +1,297 @@
1
+ """Tool and agent manifest loading + validation."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import date
5
+ from pathlib import Path
6
+ from typing import Any, Literal
7
+
8
+ import yaml
9
+ from pydantic import BaseModel, ConfigDict, Field
10
+
11
+
12
+ class ArgSpec(BaseModel):
13
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
14
+
15
+ name: str
16
+ type: Literal["string", "integer", "number", "boolean", "array", "object"] = "string"
17
+ required: bool = False
18
+ description: str = ""
19
+ default: Any = None
20
+ # JSON Schema for an arg that carries a STRUCTURED payload (a config, a DTO). A
21
+ # one-line `help=` can say an arg takes "a JSON object" but not what has to be in
22
+ # it, so a caller that only has the manifest has to reverse-engineer the shape from
23
+ # validation errors, one layer per attempt. Populate it from the schema the tool
24
+ # already validates against, never a hand-written copy, so the two cannot drift.
25
+ # Aliased: the manifest key stays `schema`, but a field literally named `schema`
26
+ # shadows BaseModel.schema() and pydantic warns on every import.
27
+ json_schema: dict | None = Field(default=None, alias="schema")
28
+
29
+
30
+ class SecretSpec(BaseModel):
31
+ model_config = ConfigDict(extra="forbid")
32
+
33
+ name: str
34
+ description: str = ""
35
+ optional: bool = False
36
+ """True when the tool works without this secret and only one branch of it
37
+ needs the value. Such a secret must not count against readiness: showing a
38
+ fully working tool as red teaches people to ignore the colour, and the next
39
+ genuinely missing credential reads the same as this one. The dashboard and
40
+ `list-tools` still surface it, as an optional extra rather than a blocker."""
41
+
42
+
43
+ class RoutingSpec(BaseModel):
44
+ """Optional request-routing hint, consumed by scripts/build-router.py to
45
+ build the Capability Router in CLAUDE.md. Lets a tool declare, in its own
46
+ manifest (the source of truth), the natural-language asks that should map to
47
+ it and the action to reach for first. When absent, the router falls back to
48
+ the tool description and a heuristic primary action."""
49
+ model_config = ConfigDict(extra="forbid")
50
+
51
+ triggers: list[str] = Field(default_factory=list)
52
+ primary_action: str = ""
53
+ example: str = ""
54
+
55
+
56
+ class HealthcheckSpec(BaseModel):
57
+ """Optional live-credential probe, consumed by the dashboard's validation
58
+ layer (and any 'is this actually connected' check). Declares a cheap,
59
+ read-only, side-effect-free call whose success proves the stored credential
60
+ is currently authorized - not merely present in Credential Manager.
61
+
62
+ - `action`: the action name to invoke on a dispatch tool. Empty for a flat
63
+ tool (the tool is run with no action positional).
64
+ - `args`: arg-name -> value, forwarded as `--name value` to the tool.
65
+ - `label`: optional human label for what the probe does (e.g. 'list 1 user').
66
+
67
+ When absent, the dashboard falls back to the tool's own `auth-status` action
68
+ (a soft convention), then to presence-only. MUST be read-only: it runs
69
+ unattended on every dashboard load."""
70
+ model_config = ConfigDict(extra="forbid")
71
+
72
+ action: str = ""
73
+ args: dict[str, Any] = Field(default_factory=dict)
74
+ label: str = ""
75
+
76
+
77
+ class WebSessionSpec(BaseModel):
78
+ """Declares that a tool works by driving a saved browser login (the `web`
79
+ tool's session) rather than an API credential. Lets the dashboard show a
80
+ per-tool 'Connect login' button prefilled with the right name/URL, and count
81
+ a missing session as 'needs setup' - so a colleague never has to guess a
82
+ session name or login URL.
83
+
84
+ - `name`: the session name the tool opens (matches `web save-session --name`).
85
+ - `login_url`: the URL to open for the human to log in.
86
+ - `persistent`: capture a persistent profile (IndexedDB-auth sites, e.g.
87
+ WhatsApp) instead of a storageState snapshot.
88
+ - `channel`: a real browser channel ('chrome'/'msedge'), e.g. for Google-SSO.
89
+ """
90
+ model_config = ConfigDict(extra="forbid")
91
+
92
+ name: str
93
+ login_url: str = ""
94
+ persistent: bool = False
95
+ channel: str = ""
96
+ label: str = ""
97
+
98
+
99
+ class RequirementSpec(BaseModel):
100
+ """Something that must exist ON THE MACHINE - not a Python dependency.
101
+
102
+ `uv sync` installs the venv; it does not install a browser engine, a database
103
+ driver or a codec. Those were previously discovered one incident at a time and
104
+ then hard-coded into the onboarding brief from memory, which is exactly how a
105
+ fresh install ends up looking healthy and failing at the user's first real
106
+ call: `list-tools` reports ready, the test suite passes, and the browser tools
107
+ die on their first action because the Playwright binary was never downloaded.
108
+
109
+ Declaring them makes the gap machine-checkable
110
+ (`python scripts/check-requirements.py`) instead of remembered.
111
+
112
+ - `name`: short id, e.g. `playwright-chromium`, `ffmpeg`, `odbc-sqlserver`.
113
+ - `kind`: what sort of thing it is (drives how it's presented, not logic).
114
+ - `why`: what breaks without it - written for the person reading the failure.
115
+ - `check`: a cheap shell command that exits 0 when the thing is present.
116
+ - `install`: how to get it (a winget id, a documented command).
117
+ - `auto`: the tool installs it itself on first use, so a missing one is a
118
+ warning rather than a blocker (ffmpeg does this via tools/_lib/ffmpeg.py).
119
+ """
120
+ model_config = ConfigDict(extra="forbid")
121
+
122
+ name: str
123
+ kind: Literal["binary", "browser", "driver", "service", "runtime"] = "binary"
124
+ why: str = ""
125
+ check: str = ""
126
+ install: str = ""
127
+ auto: bool = False
128
+
129
+
130
+ class ActionSpec(BaseModel):
131
+ """One action of a multi-action (dispatch) tool.
132
+
133
+ Action-based tools take the action name as the first positional arg;
134
+ each action has its own arg set. Flat tools use `args` at the top level.
135
+ """
136
+ model_config = ConfigDict(extra="forbid")
137
+
138
+ name: str
139
+ description: str = ""
140
+ args: list[ArgSpec] = Field(default_factory=list)
141
+ output_schema: str = ""
142
+ examples: list[dict] = Field(default_factory=list)
143
+
144
+
145
+ class ToolManifest(BaseModel):
146
+ model_config = ConfigDict(extra="forbid")
147
+
148
+ name: str
149
+ description: str
150
+ version: str = "0.1.0"
151
+ runtime: Literal["python"] = "python"
152
+ entrypoint: str = "main.py"
153
+ # Catalog tier for the multi-tenant PROCESIO module (spec P0.0-06 / D11):
154
+ # official - platform-owned, shared, users can't change (IsProcesio)
155
+ # template - a shipped default every workspace starts from, copy-on-write
156
+ # custom - workspace-authored
157
+ # Default 'template': a shipped tool is a default a workspace may fork. Ignored
158
+ # entirely by the local single-tenant runtime, so it changes nothing locally.
159
+ tier: Literal["official", "template", "custom"] = "template"
160
+ args: list[ArgSpec] = Field(default_factory=list)
161
+ actions: list[ActionSpec] = Field(default_factory=list)
162
+ secrets: list[SecretSpec] = Field(default_factory=list)
163
+ routing: RoutingSpec | None = None
164
+ healthcheck: HealthcheckSpec | None = None
165
+ web_session: WebSessionSpec | None = None
166
+ requires: list[RequirementSpec] = Field(default_factory=list)
167
+ output_schema: str = ""
168
+ examples: list[dict] = Field(default_factory=list)
169
+ # path is filled by the loader; not part of the YAML
170
+ path: Path | None = None
171
+
172
+ def is_action_based(self) -> bool:
173
+ return len(self.actions) > 0
174
+
175
+ def action_names(self) -> list[str]:
176
+ return [a.name for a in self.actions]
177
+
178
+ def get_action(self, name: str) -> ActionSpec | None:
179
+ for a in self.actions:
180
+ if a.name == name:
181
+ return a
182
+ return None
183
+
184
+
185
+ def load_tool(manifest_path: Path) -> ToolManifest:
186
+ raw = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
187
+ if not isinstance(raw, dict):
188
+ raise ValueError(f"{manifest_path}: top-level YAML must be a mapping")
189
+ m = ToolManifest(**raw)
190
+ m.path = manifest_path.parent
191
+ return m
192
+
193
+
194
+ class AgentManifest(BaseModel):
195
+ """Manifest for a registered agent.
196
+
197
+ An agent is invoked exactly like an action-dispatch tool (action name as the
198
+ first positional arg, JSON in / JSON out, secrets via Credential Manager), so
199
+ it shares ToolManifest's shape. It additionally declares `tools`: the names of
200
+ registered tools it orchestrates. The runtime resolves those via the registry,
201
+ never a hardcoded list.
202
+ """
203
+ model_config = ConfigDict(extra="forbid")
204
+
205
+ name: str
206
+ description: str
207
+ version: str = "0.1.0"
208
+ runtime: Literal["python"] = "python"
209
+ entrypoint: str = "main.py"
210
+ # Catalog tier (spec P0.0-06 / D11); see ToolManifest.tier. Default 'template'.
211
+ tier: Literal["official", "template", "custom"] = "template"
212
+ tools: list[str] = Field(default_factory=list)
213
+ args: list[ArgSpec] = Field(default_factory=list)
214
+ actions: list[ActionSpec] = Field(default_factory=list)
215
+ secrets: list[SecretSpec] = Field(default_factory=list)
216
+ routing: RoutingSpec | None = None
217
+ healthcheck: HealthcheckSpec | None = None
218
+ output_schema: str = ""
219
+ examples: list[dict] = Field(default_factory=list)
220
+ # path is filled by the loader; not part of the YAML
221
+ path: Path | None = None
222
+
223
+ def is_action_based(self) -> bool:
224
+ return len(self.actions) > 0
225
+
226
+ def action_names(self) -> list[str]:
227
+ return [a.name for a in self.actions]
228
+
229
+ def get_action(self, name: str) -> ActionSpec | None:
230
+ for a in self.actions:
231
+ if a.name == name:
232
+ return a
233
+ return None
234
+
235
+
236
+ def load_agent(manifest_path: Path) -> AgentManifest:
237
+ raw = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
238
+ if not isinstance(raw, dict):
239
+ raise ValueError(f"{manifest_path}: top-level YAML must be a mapping")
240
+ m = AgentManifest(**raw)
241
+ m.path = manifest_path.parent
242
+ return m
243
+
244
+
245
+ class SkillManifest(BaseModel):
246
+ """Manifest for a registered skill.
247
+
248
+ A skill is instruction/reference content (not an executable), so its native
249
+ `SKILL.md` YAML frontmatter IS its manifest — no separate file, no duplicated
250
+ metadata. The frontmatter always carries `name` + `description`; it may also
251
+ carry native keys we don't model (`license`, `allowed-tools`, etc.), so unlike
252
+ tool/agent manifests this is lenient (`extra="ignore"`) — skills are imported
253
+ artifacts we keep portable, not author from scratch.
254
+
255
+ An optional `routing:` block lets a skill curate its Capability-Router line,
256
+ exactly like a tool. When absent, the router falls back to the description.
257
+
258
+ Skills that opt into the governance discipline also carry `owner`,
259
+ `last_verified`, `baseline_version`, `eval_suite`, and `source_policy`
260
+ (the marker `check-skill-governance.py` scopes on). Imported/portable skills
261
+ omit them and default; `extra="ignore"` keeps any other native key portable.
262
+ """
263
+ model_config = ConfigDict(extra="ignore")
264
+
265
+ name: str
266
+ description: str
267
+ version: str = "0.1.0"
268
+ tier: Literal["official", "template", "custom"] = "template"
269
+ routing: RoutingSpec | None = None
270
+ owner: str = ""
271
+ last_verified: date | None = None
272
+ baseline_version: str = ""
273
+ eval_suite: str = ""
274
+ source_policy: Literal["generated", "timestamped", "static"] | None = None
275
+ # path is filled by the loader; not part of the frontmatter
276
+ path: Path | None = None
277
+
278
+
279
+ def _split_frontmatter(text: str) -> dict:
280
+ """Parse the leading `---`-delimited YAML frontmatter from a SKILL.md body."""
281
+ lines = text.splitlines()
282
+ if not lines or lines[0].strip() != "---":
283
+ raise ValueError("SKILL.md is missing its '---' YAML frontmatter")
284
+ for i in range(1, len(lines)):
285
+ if lines[i].strip() == "---":
286
+ raw = yaml.safe_load("\n".join(lines[1:i]))
287
+ if not isinstance(raw, dict):
288
+ raise ValueError("SKILL.md frontmatter must be a YAML mapping")
289
+ return raw
290
+ raise ValueError("SKILL.md frontmatter is not terminated by a closing '---'")
291
+
292
+
293
+ def load_skill(skill_md_path: Path) -> SkillManifest:
294
+ raw = _split_frontmatter(skill_md_path.read_text(encoding="utf-8"))
295
+ m = SkillManifest(**raw)
296
+ m.path = skill_md_path.parent
297
+ return m
@@ -0,0 +1,127 @@
1
+ """Read-only correspondence check for a Gate 5 commit and current skill bytes.
2
+
3
+ Historical fingerprints cover the entire committed skills subtree, exactly as the
4
+ series launcher exports it. Live correspondence covers published packages and the
5
+ behavioral/threshold contract, excluding the ledger (which must record new proof).
6
+ This verifies content identity, not the authenticity or quality of a test verdict.
7
+ Release targets must be clean source exports: bytecode/cache artifacts are rejected,
8
+ not silently ignored. Never delete a possibly active developer cache to pass a gate.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import re
14
+ import subprocess
15
+ from pathlib import Path, PurePosixPath
16
+
17
+
18
+ EXPERIMENT_FILES = {"evals/behavioral.json", "evals/gate5-thresholds.json"}
19
+
20
+
21
+ def _finding(code: str, message: str) -> list[dict[str, str]]:
22
+ return [{"skill": "<repository>", "code": code, "message": message}]
23
+
24
+
25
+ def _git(repo: Path, *args: str) -> bytes:
26
+ result = subprocess.run(["git", "-C", str(repo), *args], capture_output=True, check=False)
27
+ if result.returncode:
28
+ # Git diagnostics may include machine-local paths; never echo raw output.
29
+ raise ValueError("evaluated Git commit/tree is unavailable")
30
+ return result.stdout
31
+
32
+
33
+ def _norm(data: bytes) -> bytes:
34
+ """Content, made newline-agnostic. SVN materialises CRLF where Git keeps LF, so
35
+ a fingerprint over raw bytes reads the same corpus as tampered on one VCS and
36
+ intact on the other (the recorded values are the LF hashes). Normalise CRLF -> LF
37
+ for text; leave binary (anything with a NUL) untouched, so a font or image is
38
+ compared byte-for-byte as before."""
39
+ return data if b"\x00" in data else data.replace(b"\r\n", b"\n")
40
+
41
+
42
+ def _snapshot(repo: Path, commit: str) -> dict[str, bytes]:
43
+ if _git(repo, "cat-file", "-t", commit).strip() != b"commit":
44
+ raise ValueError("evaluated identity must be a commit, not a tree or tag")
45
+ entries = _git(repo, "ls-tree", "-r", "-z", commit, "--", "skills").split(b"\0")
46
+ files: dict[str, bytes] = {}
47
+ for entry in filter(None, entries):
48
+ metadata, raw_path = entry.split(b"\t", 1)
49
+ mode, kind, oid = metadata.decode("ascii").split()
50
+ path = PurePosixPath(raw_path.decode("utf-8"))
51
+ if mode not in {"100644", "100755"} or kind != "blob":
52
+ raise ValueError("evaluated skills tree contains an unsupported entry")
53
+ if path.is_absolute() or ".." in path.parts or path.parts[0] != "skills":
54
+ raise ValueError("evaluated tree contains an unsafe path")
55
+ files[path.relative_to("skills").as_posix()] = _norm(_git(repo, "cat-file", "blob", oid))
56
+ if not files:
57
+ raise ValueError("evaluated skills tree is empty")
58
+ return files
59
+
60
+
61
+ def _digest(files: dict[str, bytes]) -> str:
62
+ digest = hashlib.sha256()
63
+ # Match sorted(Path.rglob()) in the frozen series launcher, not raw string
64
+ # ordering: a directory's children sort before a similarly prefixed sibling.
65
+ for name in sorted(files, key=PurePosixPath):
66
+ digest.update(name.encode("utf-8") + b"\0" + files[name] + b"\0")
67
+ return digest.hexdigest()
68
+
69
+
70
+ def _packages(files: dict[str, bytes]) -> set[str]:
71
+ return {name.split("/")[0] for name in files
72
+ if len(PurePosixPath(name).parts) == 2 and name.endswith("/SKILL.md")}
73
+
74
+
75
+ def _projection(files: dict[str, bytes]) -> dict[str, bytes]:
76
+ packages = _packages(files)
77
+ return {name: data for name, data in files.items()
78
+ if name.split("/")[0] in packages or name in EXPERIMENT_FILES}
79
+
80
+
81
+ def _live(root: Path) -> dict[str, bytes]:
82
+ if root.is_symlink() or not root.is_dir():
83
+ raise ValueError("current skill root is missing or symlinked")
84
+ files: dict[str, bytes] = {}
85
+ for folder in root.iterdir():
86
+ if folder.is_symlink():
87
+ raise ValueError("current skills contain a symlinked directory")
88
+ if not folder.is_dir() or not (folder / "SKILL.md").exists():
89
+ continue
90
+ for path in folder.rglob("*"):
91
+ rel = path.relative_to(root)
92
+ if path.is_symlink():
93
+ raise ValueError("current skill package contains a symlink")
94
+ if "__pycache__" in rel.parts or path.suffix.lower() in {".pyc", ".pyo"}:
95
+ raise ValueError("release binding requires a clean source export without bytecode")
96
+ if path.is_file():
97
+ files[rel.as_posix()] = _norm(path.read_bytes())
98
+ for name in EXPERIMENT_FILES:
99
+ path = root / name
100
+ if path.parent.is_symlink() or path.is_symlink():
101
+ raise ValueError("current experiment contract contains a symlink")
102
+ if path.is_file():
103
+ files[name] = _norm(path.read_bytes())
104
+ return files
105
+
106
+
107
+ def check_release_binding(repo_root: Path, skills_root: Path, commit: object,
108
+ fingerprint: object) -> list[dict[str, str]]:
109
+ if (not isinstance(commit, str) or not re.fullmatch(r"[0-9a-f]{40}", commit)
110
+ or not isinstance(fingerprint, str)
111
+ or not re.fullmatch(r"[0-9a-f]{64}", fingerprint)):
112
+ return _finding("invalid-release-binding", "Gate 5 needs an exact commit and SHA-256 fingerprint")
113
+ try:
114
+ frozen = _snapshot(repo_root, commit)
115
+ except (OSError, ValueError, UnicodeError):
116
+ return _finding("unavailable-release-snapshot", "Cannot read a safe evaluated skills tree")
117
+ if _digest(frozen) != fingerprint:
118
+ return _finding("release-snapshot-mismatch", "Recorded fingerprint does not match evaluated Git tree")
119
+ try:
120
+ live = _live(skills_root)
121
+ except (OSError, ValueError):
122
+ return _finding("unsafe-release-content", "Require readable source packages without symlinks or bytecode/cache artifacts; use a clean export")
123
+ expected = _projection(frozen)
124
+ if not _packages(expected) or _packages(live) != _packages(expected) or live != expected:
125
+ changed = sum(live.get(name) != expected.get(name) for name in live.keys() | expected.keys())
126
+ return _finding("release-content-drift", f"Current packages/experiment differ from evaluated content ({changed} paths)")
127
+ return []
@@ -0,0 +1,118 @@
1
+ """Safe indexing and retrieval for bundled Agent Skill resources."""
2
+ from __future__ import annotations
3
+
4
+ import mimetypes
5
+ from pathlib import Path, PurePosixPath
6
+ from typing import Any
7
+
8
+ RESOURCE_CATEGORIES = ("references", "scripts", "assets")
9
+ MAX_TEXT_BYTES = 512_000
10
+
11
+
12
+ class SkillResourceError(ValueError):
13
+ code = "invalid_skill_resource"
14
+
15
+
16
+ class SkillResourceNotFound(SkillResourceError):
17
+ code = "skill_resource_not_found"
18
+
19
+
20
+ class SkillResourceNotText(SkillResourceError):
21
+ code = "skill_resource_not_text"
22
+
23
+
24
+ def _media_type(path: Path) -> str:
25
+ guessed, _ = mimetypes.guess_type(path.name)
26
+ if guessed:
27
+ return guessed
28
+ if path.suffix.lower() in {".md", ".markdown"}:
29
+ return "text/markdown"
30
+ return "text/plain"
31
+
32
+
33
+ def _resource_paths(root: Path, category: str) -> list[Path]:
34
+ folder = root / category
35
+ if not folder.is_dir():
36
+ return []
37
+ paths: list[Path] = []
38
+ for path in folder.rglob("*"):
39
+ if not path.is_file():
40
+ continue
41
+ try:
42
+ resolved = path.resolve(strict=True)
43
+ except (FileNotFoundError, OSError):
44
+ continue
45
+ if root != resolved and root not in resolved.parents:
46
+ continue
47
+ paths.append(path)
48
+ return sorted(paths)
49
+
50
+
51
+ def resource_index(root: Path) -> dict[str, Any]:
52
+ """Return a bounded metadata index without loading resource contents."""
53
+ root = root.resolve()
54
+ categories: dict[str, list[str]] = {}
55
+ resources: list[dict[str, Any]] = []
56
+ for category in RESOURCE_CATEGORIES:
57
+ paths = _resource_paths(root, category)
58
+ rels = [path.relative_to(root).as_posix() for path in paths]
59
+ categories[category] = rels
60
+ for path, rel in zip(paths, rels):
61
+ resources.append({
62
+ "path": rel,
63
+ "category": category,
64
+ "size": path.stat().st_size,
65
+ "media_type": _media_type(path),
66
+ })
67
+ return {**categories, "resources": resources}
68
+
69
+
70
+ def _requested_path(requested: str) -> PurePosixPath:
71
+ value = str(requested or "").strip().replace("\\", "/")
72
+ if not value:
73
+ raise SkillResourceError("resource path is required")
74
+ path = PurePosixPath(value)
75
+ if path.is_absolute() or ".." in path.parts:
76
+ raise SkillResourceError("resource path must stay inside the skill")
77
+ if len(path.parts) < 2 or path.parts[0] not in RESOURCE_CATEGORIES:
78
+ allowed = ", ".join(f"{item}/" for item in RESOURCE_CATEGORIES)
79
+ raise SkillResourceError(f"resource path must start with one of: {allowed}")
80
+ return path
81
+
82
+
83
+ def read_text_resource(root: Path, requested: str,
84
+ max_bytes: int = MAX_TEXT_BYTES) -> dict[str, Any]:
85
+ """Read one UTF-8 resource, rejecting traversal, symlink escape, and huge files."""
86
+ relative = _requested_path(requested)
87
+ if "\x00" in str(relative):
88
+ raise SkillResourceError("resource path contains a null byte")
89
+ try:
90
+ root_resolved = root.resolve()
91
+ candidate = root_resolved.joinpath(*relative.parts)
92
+ resolved = candidate.resolve(strict=True)
93
+ if root_resolved != resolved and root_resolved not in resolved.parents:
94
+ raise SkillResourceError("resource resolves outside the skill root")
95
+ if not resolved.is_file():
96
+ raise SkillResourceNotFound(f"resource is not a file: {relative.as_posix()}")
97
+ size = resolved.stat().st_size
98
+ if size > max_bytes:
99
+ raise SkillResourceError(
100
+ f"resource is {size} bytes; maximum retrievable size is {max_bytes}"
101
+ )
102
+ content = resolved.read_text(encoding="utf-8")
103
+ except FileNotFoundError as exc:
104
+ raise SkillResourceNotFound(f"resource not found: {relative.as_posix()}") from exc
105
+ except UnicodeDecodeError as exc:
106
+ raise SkillResourceNotText(
107
+ f"resource is not UTF-8 text: {relative.as_posix()}"
108
+ ) from exc
109
+ except OSError as exc:
110
+ # OS messages may contain absolute installation paths; never emit them.
111
+ raise SkillResourceError("resource could not be read") from exc
112
+ return {
113
+ "path": relative.as_posix(),
114
+ "category": relative.parts[0],
115
+ "size": size,
116
+ "media_type": _media_type(resolved),
117
+ "content": content,
118
+ }