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,584 @@
1
+ #!/usr/bin/env python3
2
+ """Scan tracked files for live-credential formats.
3
+
4
+ Backs Hard rule 1 ("No secrets in files. Ever.") with a mechanical check.
5
+ Runs as a CLI (pre-commit hook) and as an importable module (pytest guard).
6
+
7
+ Two properties matter more than the pattern list:
8
+
9
+ 1. **Windowed reads.** A single-line 30 MB JSON export is normal here
10
+ (a .procesio export is one enormous line). A scanner that reads by line,
11
+ or that skips lines over some length, silently reports "clean" on exactly
12
+ the files most likely to carry a secret. This reads fixed-size chunks with
13
+ an overlap wider than the longest credential we match, so a token straddling
14
+ a chunk boundary is still found.
15
+
16
+ 2. **Shape classification before reporting.** Most `Bearer <x>` occurrences in
17
+ a workflow export are GUIDs - variable references, not secrets. Classifying
18
+ by shape (guid / placeholder / jwt / opaque-high-entropy) is what keeps the
19
+ signal usable; without it the true positives drown.
20
+
21
+ Never emits a credential value. A finding is identified by sha256 prefix,
22
+ length and Shannon entropy, which is enough to match it against a vault entry
23
+ or to confirm a rotation without ever moving the secret itself.
24
+ """
25
+
26
+ from __future__ import annotations
27
+
28
+ import argparse
29
+ import base64
30
+ import binascii
31
+ import hashlib
32
+ import json
33
+ import math
34
+ import os
35
+ import re
36
+ import subprocess
37
+ import sys
38
+ from collections import Counter
39
+ from dataclasses import dataclass, asdict
40
+ from pathlib import Path
41
+ from xml.etree import ElementTree
42
+
43
+ REPO_ROOT = Path(__file__).resolve().parent.parent
44
+
45
+ # Read 4 MB at a time, overlapping by 64 KB. The overlap must exceed the
46
+ # longest single token we can match (a long JWT); 64 KB is far above that.
47
+ CHUNK_BYTES = 4 * 1024 * 1024
48
+ OVERLAP_BYTES = 64 * 1024
49
+
50
+ # Entropy floor for calling an opaque string a credential, in bits/char.
51
+ # Hex-only tokens sit near 4.0, base64url near 5.5; English prose and
52
+ # dotted identifiers sit well below 3.2.
53
+ MIN_ENTROPY = 3.2
54
+ MIN_OPAQUE_LEN = 20
55
+
56
+ GUID_RE = re.compile(
57
+ r"\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-"
58
+ r"[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\Z"
59
+ )
60
+
61
+ # Substrings that mark a value as a documentation placeholder rather than a
62
+ # live credential. Compared case-insensitively.
63
+ PLACEHOLDER_MARKERS = (
64
+ "xxxx", "your", "example", "placeholder", "changeme", "redacted",
65
+ "sample", "dummy", "insert", "replace", "<", ">", "{{", "}}", "...",
66
+ "abc123", "todo", "notarealkey", "scrubbed",
67
+ )
68
+
69
+ # Each rule: (name, compiled pattern, needs_entropy_check)
70
+ # Patterns are byte patterns - we scan bytes so we never have to guess an
71
+ # encoding on a 30 MB file.
72
+ RULES: list[tuple[str, re.Pattern[bytes], bool]] = [
73
+ ("google-api-key", re.compile(rb"AIza[0-9A-Za-z_\-]{35}"), False),
74
+ ("openai-key", re.compile(rb"\bsk-(?:proj-|ant-)?[A-Za-z0-9_\-]{20,}"), True),
75
+ ("github-pat", re.compile(rb"\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}"), False),
76
+ ("github-fine-grained-pat", re.compile(rb"\bgithub_pat_[A-Za-z0-9_]{22,}"), False),
77
+ ("slack-token", re.compile(rb"\bxox[abposr]-[A-Za-z0-9\-]{10,}"), False),
78
+ ("aws-access-key-id", re.compile(rb"\bAKIA[0-9A-Z]{16}\b"), False),
79
+ ("sendgrid-key", re.compile(rb"\bSG\.[A-Za-z0-9_\-]{22}\.[A-Za-z0-9_\-]{43}"), False),
80
+ (
81
+ "jwt",
82
+ re.compile(rb"\beyJ[A-Za-z0-9_\-]{8,}\.eyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]*"),
83
+ False,
84
+ ),
85
+ (
86
+ "private-key-pem",
87
+ re.compile(rb"-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----"),
88
+ False,
89
+ ),
90
+ ("twilio-account-sid", re.compile(rb"\bAC[0-9a-f]{32}\b"), False),
91
+ ("twilio-api-key", re.compile(rb"\bSK[0-9a-f]{32}\b"), False),
92
+ ("stripe-key", re.compile(rb"\b[rs]k_(?:live|test)_[A-Za-z0-9]{20,}"), False),
93
+ # Authorization headers. These fire constantly on GUID variable
94
+ # references, so the shape classifier below does the real work.
95
+ (
96
+ "http-authorization",
97
+ re.compile(rb"(?:Bearer|Basic)\s+([A-Za-z0-9_\-\.=+/]{20,})"),
98
+ True,
99
+ ),
100
+ ]
101
+
102
+ # Rules whose match is an identifier rather than a usable secret on its own.
103
+ # Still reported, at lower severity, because they name the account to rotate.
104
+ IDENTIFIER_ONLY = {"twilio-account-sid", "aws-access-key-id"}
105
+
106
+
107
+ # A run of base64 / base64url characters long enough to wrap a credential.
108
+ # Kept well above incidental identifiers (a GUID is 32 hex + dashes) so we do
109
+ # not try to decode every high-entropy token in a workflow export.
110
+ MIN_B64_RUN = 40
111
+ _B64_RUN = re.compile(rb"[A-Za-z0-9+/_\-]{%d,}={0,2}" % MIN_B64_RUN)
112
+
113
+ # How many base64 layers to peel. A Kubernetes dockerconfigjson Secret buries
114
+ # the token two layers down: the `.dockerconfigjson` value is base64 of a JSON
115
+ # doc whose `auth` field is itself base64 of `user:token`. Three peels reach it
116
+ # with a layer to spare, and bound the work on a large export.
117
+ MAX_DECODE_DEPTH = 3
118
+
119
+
120
+ def _try_b64_decode(run: bytes) -> bytes | None:
121
+ """Decode a base64 / base64url run, or None if it is not really base64.
122
+
123
+ Only returns a decode that is overwhelmingly printable: a wrapped
124
+ credential (and the JSON or `user:token` around it) is text, whereas a
125
+ random high-entropy identifier that merely looks base64-shaped decodes to
126
+ binary noise not worth recursing into.
127
+ """
128
+ body = run.rstrip(b"=").replace(b"-", b"+").replace(b"_", b"/")
129
+ body += b"=" * ((-len(body)) % 4)
130
+ try:
131
+ decoded = base64.b64decode(body, validate=True)
132
+ except (binascii.Error, ValueError):
133
+ return None
134
+ if len(decoded) < 3:
135
+ return None
136
+ printable = sum(1 for b in decoded if b in (9, 10, 13) or 32 <= b <= 126)
137
+ if printable / len(decoded) < 0.85:
138
+ return None
139
+ return decoded
140
+
141
+
142
+ def shannon_entropy(data: str) -> float:
143
+ """Bits of entropy per character."""
144
+ if not data:
145
+ return 0.0
146
+ counts = Counter(data)
147
+ total = len(data)
148
+ return -sum(
149
+ (c / total) * math.log2(c / total) for c in counts.values()
150
+ )
151
+
152
+
153
+ def fingerprint(value: str) -> str:
154
+ """Stable, non-reversible id for a secret. Safe to print, log and commit."""
155
+ return hashlib.sha256(value.encode("utf-8", "replace")).hexdigest()[:12]
156
+
157
+
158
+ def classify(value: str) -> str:
159
+ """Shape of a candidate: guid | placeholder | jwt | opaque | low-entropy."""
160
+ stripped = value.strip().strip("\"'")
161
+ if GUID_RE.match(stripped):
162
+ return "guid"
163
+ lowered = stripped.lower()
164
+ if any(marker in lowered for marker in PLACEHOLDER_MARKERS):
165
+ return "placeholder"
166
+ if len(set(stripped)) <= 2:
167
+ return "placeholder"
168
+ if stripped.startswith("eyJ") and stripped.count(".") >= 2:
169
+ return "jwt"
170
+ if len(stripped) < MIN_OPAQUE_LEN:
171
+ return "low-entropy"
172
+ if shannon_entropy(stripped) < MIN_ENTROPY:
173
+ return "low-entropy"
174
+ return "opaque"
175
+
176
+
177
+ @dataclass
178
+ class Finding:
179
+ path: str
180
+ rule: str
181
+ shape: str
182
+ fingerprint: str
183
+ length: int
184
+ entropy: float
185
+ offset: int
186
+ severity: str
187
+
188
+ def render(self) -> str:
189
+ return (
190
+ f" {self.severity:<10} {self.rule:<24} shape={self.shape:<11} "
191
+ f"sha256:{self.fingerprint} len={self.length:<4} "
192
+ f"entropy={self.entropy:.2f} @byte {self.offset}"
193
+ )
194
+
195
+
196
+ def _decode(raw: bytes) -> str:
197
+ return raw.decode("utf-8", "replace")
198
+
199
+
200
+ def scan_bytes(
201
+ blob: bytes, path: str, base_offset: int = 0, _depth: int = 0
202
+ ) -> list[Finding]:
203
+ """Apply every rule to one chunk of bytes, then to base64-wrapped payloads.
204
+
205
+ A Kubernetes `dockerconfigjson` Secret hides its registry token two base64
206
+ layers deep, so the literal rules never see it on the raw bytes. After the
207
+ direct pass, decode any long base64 run and re-scan the result, down to
208
+ MAX_DECODE_DEPTH layers.
209
+ """
210
+ findings: list[Finding] = []
211
+ for rule_name, pattern, entropy_gated in RULES:
212
+ for match in pattern.finditer(blob):
213
+ # Group 1 when the rule captures the value separately
214
+ # (Authorization headers), else the whole match.
215
+ raw = match.group(1) if pattern.groups else match.group(0)
216
+ value = _decode(raw)
217
+ shape = classify(value)
218
+
219
+ if shape in ("guid", "placeholder", "low-entropy"):
220
+ # A GUID after Bearer is a PROCESIO variable reference; a
221
+ # placeholder is documentation. Neither is a secret.
222
+ if entropy_gated or shape != "low-entropy":
223
+ continue
224
+
225
+ if rule_name == "private-key-pem":
226
+ severity = "CRITICAL"
227
+ elif rule_name in IDENTIFIER_ONLY:
228
+ severity = "INFO"
229
+ else:
230
+ severity = "CRITICAL"
231
+
232
+ findings.append(
233
+ Finding(
234
+ path=path,
235
+ rule=rule_name,
236
+ shape=shape,
237
+ fingerprint=fingerprint(value),
238
+ length=len(value),
239
+ entropy=round(shannon_entropy(value), 2),
240
+ offset=base_offset + match.start(),
241
+ severity=severity,
242
+ )
243
+ )
244
+
245
+ if _depth < MAX_DECODE_DEPTH:
246
+ for run in _B64_RUN.finditer(blob):
247
+ decoded = _try_b64_decode(run.group(0))
248
+ if decoded is None:
249
+ continue
250
+ for nested in scan_bytes(decoded, path, 0, _depth + 1):
251
+ # Byte offsets inside a decoded blob do not map back to the
252
+ # file; pin the finding to the wrapper run the reviewer scrubs.
253
+ nested.offset = base_offset + run.start()
254
+ findings.append(nested)
255
+ return findings
256
+
257
+
258
+ def scan_file(path: Path, display: str | None = None) -> list[Finding]:
259
+ """Scan one file with overlapping windows.
260
+
261
+ Never reads the whole file into memory and never splits on newlines, so a
262
+ 30 MB single-line JSON export is scanned exactly like any other file.
263
+ """
264
+ display = display or str(path)
265
+ findings: list[Finding] = []
266
+ seen: set[tuple[str, str, str]] = set()
267
+
268
+ try:
269
+ size = path.stat().st_size
270
+ except OSError:
271
+ return findings
272
+ if size == 0:
273
+ return findings
274
+
275
+ with path.open("rb") as handle:
276
+ offset = 0
277
+ carry = b""
278
+ carry_offset = 0
279
+ while True:
280
+ chunk = handle.read(CHUNK_BYTES)
281
+ if not chunk:
282
+ break
283
+ window = carry + chunk
284
+ window_offset = carry_offset if carry else offset
285
+ for finding in scan_bytes(window, display, window_offset):
286
+ # The overlap means a token near a boundary is matched twice.
287
+ key = (finding.rule, finding.fingerprint, str(finding.offset))
288
+ dedup = (finding.rule, finding.fingerprint, "")
289
+ if dedup in seen:
290
+ continue
291
+ seen.add(dedup)
292
+ findings.append(finding)
293
+ offset += len(chunk)
294
+ carry = window[-OVERLAP_BYTES:]
295
+ carry_offset = offset - len(carry)
296
+ return findings
297
+
298
+
299
+ def detect_vcs(root: Path) -> list[str]:
300
+ """Which version-control systems govern this working copy.
301
+
302
+ This repo is deliberately dual-VCS - one team consumes it over Git, the
303
+ other over SVN - so "what gets published" has two answers, and a scanner
304
+ that knows only one of them is inoperative for the other team. That was
305
+ the bug: an SVN-only checkout has no `.git`, `git ls-files` exited 128,
306
+ and the guard raised instead of guarding.
307
+
308
+ Both are returned when both are present (the mirror host holds both
309
+ working copies). The union is scanned rather than either alone: a file
310
+ versioned on only one side still reaches that side's team.
311
+
312
+ `.git` is matched as a path, not a directory - a worktree or submodule
313
+ checkout carries a `.git` *file* pointing at the real git dir.
314
+ """
315
+ found: list[str] = []
316
+ if (root / ".git").exists():
317
+ found.append("git")
318
+ if (root / ".svn").is_dir():
319
+ found.append("svn")
320
+ return found
321
+
322
+
323
+ class NoVersionControl(RuntimeError):
324
+ """Raised when the scan scope cannot be determined from the working copy."""
325
+
326
+
327
+ def _decode_nul_list(payload: bytes) -> list[str]:
328
+ return [name.decode("utf-8") for name in payload.split(b"\0") if name]
329
+
330
+
331
+ def _run_vcs(cmd: list[str], root: Path) -> bytes:
332
+ """Run a VCS query, turning a non-zero exit into a legible failure.
333
+
334
+ A CalledProcessError from deep inside the guard reads as "the scanner is
335
+ broken"; for a check whose whole job is to refuse to pass silently, the
336
+ failure has to say which command failed and in which working copy.
337
+ """
338
+ result = subprocess.run(cmd, cwd=root, capture_output=True)
339
+ if result.returncode != 0:
340
+ raise NoVersionControl(
341
+ f"{' '.join(cmd[:2])} failed in {root} (exit {result.returncode}): "
342
+ + (result.stderr.decode("utf-8", "replace").strip() or "no stderr")
343
+ )
344
+ return result.stdout
345
+
346
+
347
+ # --------------------------------------------------------------------------
348
+ # git
349
+ # --------------------------------------------------------------------------
350
+
351
+ def _git_tracked(root: Path) -> list[str]:
352
+ return _decode_nul_list(_run_vcs(["git", "ls-files", "-z"], root))
353
+
354
+
355
+ def _git_changed(root: Path) -> list[str]:
356
+ return _decode_nul_list(
357
+ _run_vcs(
358
+ ["git", "diff", "--cached", "--name-only", "--diff-filter=ACM", "-z"],
359
+ root,
360
+ )
361
+ )
362
+
363
+
364
+ # --------------------------------------------------------------------------
365
+ # svn
366
+ # --------------------------------------------------------------------------
367
+
368
+ # `svn status` item kinds that are NOT part of what a commit publishes.
369
+ # Everything else is scanned, including kinds not listed here: for a guard,
370
+ # an unrecognised state must fall through to "scan it", never to "skip it".
371
+ SVN_UNPUBLISHED = frozenset(
372
+ {"unversioned", "ignored", "external", "missing", "deleted", "none"}
373
+ )
374
+
375
+ # Item kinds that represent a local change - the SVN answer to "staged".
376
+ SVN_LOCAL_CHANGE = frozenset({"added", "modified", "replaced", "conflicted", "merged"})
377
+
378
+
379
+ def _svn_status_entries(root: Path, verbose: bool) -> list[tuple[str, str]]:
380
+ """(path, item-kind) for every entry `svn status` reports.
381
+
382
+ `--xml` rather than the columnar default: the plain output is fixed-width
383
+ and positional, which mis-parses a path containing spaces - and this tree
384
+ has them. `svn status` is a working-copy operation and needs no network,
385
+ unlike `svn list -R`, which queries the repository and would make the
386
+ guard fail offline and hang a pre-commit hook.
387
+ """
388
+ cmd = ["svn", "status", "--xml", "--no-ignore"]
389
+ if verbose:
390
+ cmd.append("--verbose")
391
+ payload = _run_vcs(cmd, root)
392
+
393
+ entries: list[tuple[str, str]] = []
394
+ for entry in ElementTree.fromstring(payload).iter("entry"):
395
+ path = entry.get("path")
396
+ if not path or path == ".":
397
+ continue
398
+ status = entry.find("wc-status")
399
+ item = status.get("item", "") if status is not None else ""
400
+ entries.append((path, item))
401
+ return entries
402
+
403
+
404
+ def _svn_versioned(root: Path) -> list[str]:
405
+ """Every file SVN has under version control in this working copy."""
406
+ return [
407
+ path
408
+ for path, item in _svn_status_entries(root, verbose=True)
409
+ if item not in SVN_UNPUBLISHED
410
+ ]
411
+
412
+
413
+ def _svn_changed(root: Path) -> list[str]:
414
+ """Locally changed files - what `svn commit` would send.
415
+
416
+ SVN has no index, so nothing is literally "staged"; the closest honest
417
+ equivalent is the set of local modifications.
418
+ """
419
+ return [
420
+ path
421
+ for path, item in _svn_status_entries(root, verbose=False)
422
+ if item in SVN_LOCAL_CHANGE
423
+ ]
424
+
425
+
426
+ # --------------------------------------------------------------------------
427
+ # backend-agnostic entry points
428
+ # --------------------------------------------------------------------------
429
+
430
+ # backend -> (full-scope enumerator, local-change enumerator)
431
+ _ENUMERATORS = {
432
+ "git": (_git_tracked, _git_changed),
433
+ "svn": (_svn_versioned, _svn_changed),
434
+ }
435
+
436
+
437
+ def _collect(root: Path, index: int) -> list[Path]:
438
+ backends = detect_vcs(root)
439
+ if not backends:
440
+ raise NoVersionControl(
441
+ f"no .git or .svn in {root} - cannot determine which files are "
442
+ "published, and a secret scan over an unknown scope proves nothing"
443
+ )
444
+ names: set[str] = set()
445
+ for backend in backends:
446
+ names.update(_ENUMERATORS[backend][index](root))
447
+ return sorted({(root / name) for name in names}, key=str)
448
+
449
+
450
+ def tracked_files(root: Path) -> list[Path]:
451
+ """Every file this working copy publishes, so the guard covers exactly that.
452
+
453
+ Git or SVN, or the union of both when the machine holds both.
454
+
455
+ Files only. `git ls-files` never names a directory, but `svn status -v`
456
+ reports one entry per versioned directory too, and counting those as
457
+ "scanned" overstates the guard's coverage by a fifth of the tree.
458
+ """
459
+ return [p for p in _collect(root, 0) if p.is_file()]
460
+
461
+
462
+ def staged_files(root: Path) -> list[Path]:
463
+ """Files a commit from here would carry - the pre-commit hook's scope."""
464
+ return [p for p in _collect(root, 1) if p.is_file()]
465
+
466
+
467
+ def load_allowlist(root: Path) -> set[str]:
468
+ """Fingerprints reviewed and accepted as non-secret.
469
+
470
+ Holds fingerprints, never values - so the allowlist itself is safe to
471
+ commit. Add an entry only after confirming the value is not live.
472
+ """
473
+ path = root / ".secret-scan-allowlist"
474
+ if not path.exists():
475
+ return set()
476
+ entries = set()
477
+ for line in path.read_text(encoding="utf-8").splitlines():
478
+ line = line.split("#", 1)[0].strip()
479
+ if line:
480
+ entries.add(line)
481
+ return entries
482
+
483
+
484
+ def _is_vcs_internal(rel: str) -> bool:
485
+ """VCS metadata directories, which are never published content.
486
+
487
+ `.svn` matters more than `.git` here: `.svn/pristine` holds a complete
488
+ copy of every versioned file, so a directory scan that descends into it
489
+ reports each finding twice and - worse - keeps reporting a secret out of
490
+ the pristine copy after the working file has been scrubbed, which reads
491
+ as "the scrub did not work".
492
+ """
493
+ # Separators are normalised because `rel` falls back to a native
494
+ # absolute path when the target sits outside the repo root, and on
495
+ # Windows that arrives backslash-separated.
496
+ return any(
497
+ part in (".git", ".svn")
498
+ for part in rel.replace("\\", "/").split("/")
499
+ )
500
+
501
+
502
+ def scan_paths(paths: list[Path], root: Path) -> list[Finding]:
503
+ allowed = load_allowlist(root)
504
+ findings: list[Finding] = []
505
+ for path in paths:
506
+ if not path.is_file():
507
+ continue
508
+ try:
509
+ rel = path.relative_to(root).as_posix()
510
+ except ValueError:
511
+ rel = str(path)
512
+ if rel == ".secret-scan-allowlist" or _is_vcs_internal(rel):
513
+ continue
514
+ for finding in scan_file(path, rel):
515
+ if finding.fingerprint in allowed:
516
+ continue
517
+ findings.append(finding)
518
+ return findings
519
+
520
+
521
+ def main() -> int:
522
+ parser = argparse.ArgumentParser(
523
+ description="Scan for live-credential formats in tracked files."
524
+ )
525
+ parser.add_argument(
526
+ "--staged",
527
+ action="store_true",
528
+ help="Scan only files staged for commit (pre-commit hook mode).",
529
+ )
530
+ parser.add_argument(
531
+ "--path",
532
+ action="append",
533
+ default=[],
534
+ help="Scan a specific file or directory (repeatable).",
535
+ )
536
+ parser.add_argument("--json", action="store_true", help="Emit JSON.")
537
+ args = parser.parse_args()
538
+
539
+ if args.path:
540
+ targets: list[Path] = []
541
+ for entry in args.path:
542
+ p = Path(entry)
543
+ if not p.is_absolute():
544
+ p = REPO_ROOT / entry
545
+ targets.extend(sorted(q for q in p.rglob("*") if q.is_file()) if p.is_dir() else [p])
546
+ elif args.staged:
547
+ targets = staged_files(REPO_ROOT)
548
+ else:
549
+ targets = tracked_files(REPO_ROOT)
550
+
551
+ findings = scan_paths(targets, REPO_ROOT)
552
+ blocking = [f for f in findings if f.severity == "CRITICAL"]
553
+
554
+ if args.json:
555
+ print(json.dumps([asdict(f) for f in findings], indent=2))
556
+ else:
557
+ if not findings:
558
+ print(f"secret-scan: clean ({len(targets)} files scanned)")
559
+ else:
560
+ by_path: dict[str, list[Finding]] = {}
561
+ for f in findings:
562
+ by_path.setdefault(f.path, []).append(f)
563
+ print(
564
+ f"secret-scan: {len(findings)} finding(s) in "
565
+ f"{len(by_path)} file(s) of {len(targets)} scanned\n"
566
+ )
567
+ for path, group in sorted(by_path.items()):
568
+ print(f"{path}")
569
+ for f in sorted(group, key=lambda x: x.offset):
570
+ print(f.render())
571
+ print()
572
+ if blocking:
573
+ print(
574
+ "Values are never printed. Identify a secret by its sha256 "
575
+ "prefix.\nRotate it at the source, scrub the file, then "
576
+ "re-scan. If a finding is\nconfirmed not live, add its "
577
+ "fingerprint to .secret-scan-allowlist."
578
+ )
579
+
580
+ return 1 if blocking else 0
581
+
582
+
583
+ if __name__ == "__main__":
584
+ sys.exit(main())