@daniellins/power-claude 0.16.3

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.

Potentially problematic release.


This version of @daniellins/power-claude might be problematic. Click here for more details.

Files changed (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/bin/cli.js +124 -0
  4. package/installer/__tests__/doctor-ready-oracles.test.cjs +140 -0
  5. package/installer/__tests__/merge-settings.test.cjs +330 -0
  6. package/installer/adopt.js +161 -0
  7. package/installer/copy.js +203 -0
  8. package/installer/doctor.js +266 -0
  9. package/installer/install.js +155 -0
  10. package/installer/manifest.js +102 -0
  11. package/installer/motor-scripts.js +50 -0
  12. package/installer/motor-scripts.json +39 -0
  13. package/installer/uninstall.js +99 -0
  14. package/installer/update.js +376 -0
  15. package/installer/util.js +113 -0
  16. package/installer/wizard.js +64 -0
  17. package/package.json +26 -0
  18. package/scripts/__fixtures__/anti-path-demo/agents/ap-writer.md +13 -0
  19. package/scripts/__fixtures__/anti-path-demo/templates/write-tmpl.md +7 -0
  20. package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.smoke.json +10 -0
  21. package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.yaml +25 -0
  22. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/agents/content-chief.md +1 -0
  23. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/workflows/wf-criacao-redteam.yaml +3 -0
  24. package/scripts/__fixtures__/assess-tier/retrofit-leve/pod-spec.json +13 -0
  25. package/scripts/__fixtures__/fidelity/fake-green-average-in-band.yaml +21 -0
  26. package/scripts/__fixtures__/fidelity/fake-green-average.yaml +18 -0
  27. package/scripts/__fixtures__/fidelity/fake-green-denominator.yaml +19 -0
  28. package/scripts/__fixtures__/fidelity/fake-green-missing-evidence.yaml +18 -0
  29. package/scripts/__fixtures__/fidelity/fake-green-threshold.yaml +18 -0
  30. package/scripts/__fixtures__/fidelity/fake-green-weight.yaml +18 -0
  31. package/scripts/__fixtures__/fidelity/golden.yaml +31 -0
  32. package/scripts/__fixtures__/fidelity/trindade-incoherent.yaml +15 -0
  33. package/scripts/__fixtures__/forge-canonical/pod-spec-example.json +37 -0
  34. package/scripts/__fixtures__/migrate-squad/authored/agents/offer-engineer.md +17 -0
  35. package/scripts/__fixtures__/migrate-squad/authored/knowledge/no-source.md +7 -0
  36. package/scripts/__fixtures__/migrate-squad/authored/knowledge/value-stack-method.md +8 -0
  37. package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.smoke.json +24 -0
  38. package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.spec.json +45 -0
  39. package/scripts/__fixtures__/migrate-squad/legacy-squad/HEADLINE.md +3 -0
  40. package/scripts/__fixtures__/migrate-squad/legacy-squad/README.md +4 -0
  41. package/scripts/__fixtures__/migrate-squad/legacy-squad/agents/hormozi-offer.md +14 -0
  42. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/dead-redundant.md +4 -0
  43. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/method-guide.md +6 -0
  44. package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/veto-screen.md +4 -0
  45. package/scripts/__fixtures__/migrate-squad/legacy-squad/config/config.yaml +2 -0
  46. package/scripts/__fixtures__/migrate-squad/legacy-squad/data/case-library.md +3 -0
  47. package/scripts/__fixtures__/migrate-squad/legacy-squad/scripts/validate-mvn.py +16 -0
  48. package/scripts/__fixtures__/migrate-squad/legacy-squad/sops/sop-sample.md +3 -0
  49. package/scripts/__fixtures__/migrate-squad/legacy-squad/squad-io.yaml +14 -0
  50. package/scripts/__fixtures__/migrate-squad/legacy-squad/tasks/gather-context.md +7 -0
  51. package/scripts/__fixtures__/migrate-squad/legacy-squad/templates/output-tmpl.md +5 -0
  52. package/scripts/__fixtures__/migrate-squad/legacy-squad/workflows/wf-sample.yaml +24 -0
  53. package/scripts/__fixtures__/pipeline/pipelines/pipeline-checkpoint.yaml +21 -0
  54. package/scripts/__fixtures__/pipeline/pipelines/pipeline-demo.yaml +22 -0
  55. package/scripts/__fixtures__/pipeline/pods/pipe-a/agents/maker.md +13 -0
  56. package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.consolidated.md +8 -0
  57. package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.jsonl +83 -0
  58. package/scripts/__fixtures__/pipeline/pods/pipe-a/templates/make-tmpl.md +8 -0
  59. package/scripts/__fixtures__/pipeline/pods/pipe-a/workflows/wf-a.yaml +16 -0
  60. package/scripts/__fixtures__/pipeline/pods/pipe-b/agents/user.md +13 -0
  61. package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.consolidated.md +8 -0
  62. package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.jsonl +14 -0
  63. package/scripts/__fixtures__/pipeline/pods/pipe-b/templates/use-tmpl.md +6 -0
  64. package/scripts/__fixtures__/pipeline/pods/pipe-b/workflows/wf-b.yaml +16 -0
  65. package/scripts/__fixtures__/pod-run/agents/forge-chief.md +13 -0
  66. package/scripts/__fixtures__/pod-run/agents/pod-critic.md +13 -0
  67. package/scripts/__fixtures__/pod-run/templates/build-tmpl.md +8 -0
  68. package/scripts/__fixtures__/pod-run/templates/gate-tmpl.md +6 -0
  69. package/scripts/__fixtures__/pod-run/workflows/wf-min.yaml +43 -0
  70. package/scripts/__fixtures__/pod-run/workflows/wf-skip-modes.yaml +50 -0
  71. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-all-skippable.yaml +30 -0
  72. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-criteria-escalar-de-bloco.yaml +40 -0
  73. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-skip-mode-desconhecido.yaml +30 -0
  74. package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-unknown-key.yaml +29 -0
  75. package/scripts/__fixtures__/pod-workflow/invalid-cycle.yaml +26 -0
  76. package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-backedge.yaml +29 -0
  77. package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-forward.yaml +29 -0
  78. package/scripts/__fixtures__/pod-workflow/invalid-handoff-open.yaml +27 -0
  79. package/scripts/__fixtures__/pod-workflow/invalid-knowledge-shape.yaml +18 -0
  80. package/scripts/__fixtures__/pod-workflow/invalid-missing-agent.yaml +15 -0
  81. package/scripts/__fixtures__/pod-workflow/invalid-missing-outputs.yaml +15 -0
  82. package/scripts/__fixtures__/pod-workflow/invalid-missing-template.yaml +15 -0
  83. package/scripts/__fixtures__/pod-workflow/invalid-missing-veto.yaml +13 -0
  84. package/scripts/__fixtures__/pod-workflow/invalid-template-not-on-disk.yaml +16 -0
  85. package/scripts/__fixtures__/pod-workflow/invalid-veto-prose.yaml +17 -0
  86. package/scripts/__fixtures__/pod-workflow/knowledge/a.md +4 -0
  87. package/scripts/__fixtures__/pod-workflow/knowledge/b.md +4 -0
  88. package/scripts/__fixtures__/pod-workflow/knowledge/c.md +4 -0
  89. package/scripts/__fixtures__/pod-workflow/templates/step-tmpl.md +7 -0
  90. package/scripts/__fixtures__/pod-workflow/valid-checkpoint-skip-modes.yaml +29 -0
  91. package/scripts/__fixtures__/pod-workflow/valid-fix-loop.yaml +30 -0
  92. package/scripts/__fixtures__/pod-workflow/valid-knowledge.yaml +30 -0
  93. package/scripts/__fixtures__/pod-workflow/valid-veto-always-true.yaml +20 -0
  94. package/scripts/__fixtures__/pod-workflow/valid.yaml +27 -0
  95. package/scripts/__fixtures__/smoke-canary/agents/canary-reporter.md +13 -0
  96. package/scripts/__fixtures__/smoke-canary/agents/canary-researcher.md +13 -0
  97. package/scripts/__fixtures__/smoke-canary/agents/canary-synth.md +13 -0
  98. package/scripts/__fixtures__/smoke-canary/memory/learnings.consolidated.md +10 -0
  99. package/scripts/__fixtures__/smoke-canary/memory/learnings.jsonl +448 -0
  100. package/scripts/__fixtures__/smoke-canary/templates/report-tmpl.md +9 -0
  101. package/scripts/__fixtures__/smoke-canary/templates/research-tmpl.md +7 -0
  102. package/scripts/__fixtures__/smoke-canary/templates/synth-tmpl.md +9 -0
  103. package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.smoke.json +11 -0
  104. package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.yaml +53 -0
  105. package/scripts/__fixtures__/source-audit/fake-green-bronze-unsignaled.yaml +10 -0
  106. package/scripts/__fixtures__/source-audit/fake-green-counts.yaml +9 -0
  107. package/scripts/__fixtures__/source-audit/fake-green-missing-evidence.yaml +9 -0
  108. package/scripts/__fixtures__/source-audit/fake-green-unclassified.yaml +10 -0
  109. package/scripts/__fixtures__/source-audit/fake-green-verdict.yaml +10 -0
  110. package/scripts/__fixtures__/source-audit/golden-blocked.yaml +10 -0
  111. package/scripts/__fixtures__/source-audit/golden.yaml +11 -0
  112. package/scripts/__fixtures__/sweep-forms/agents/forms-count.md +13 -0
  113. package/scripts/__fixtures__/sweep-forms/agents/forms-field.md +13 -0
  114. package/scripts/__fixtures__/sweep-forms/agents/forms-fileref.md +13 -0
  115. package/scripts/__fixtures__/sweep-forms/agents/forms-json.md +13 -0
  116. package/scripts/__fixtures__/sweep-forms/agents/forms-section.md +13 -0
  117. package/scripts/__fixtures__/sweep-forms/specs/wf-forms.spec.json +5 -0
  118. package/scripts/__fixtures__/sweep-forms/templates/t_count.md +5 -0
  119. package/scripts/__fixtures__/sweep-forms/templates/t_field.md +3 -0
  120. package/scripts/__fixtures__/sweep-forms/templates/t_fileref.md +3 -0
  121. package/scripts/__fixtures__/sweep-forms/templates/t_json.md +0 -0
  122. package/scripts/__fixtures__/sweep-forms/templates/t_section.md +3 -0
  123. package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.smoke.json +13 -0
  124. package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.yaml +67 -0
  125. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-1-noop-state-json.fixture.md +18 -0
  126. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-2-crash-buildworkflowyaml.fixture.md +26 -0
  127. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-3-nasce-verde-skip-modes.fixture.md +29 -0
  128. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-4-guarda-sem-irmao.fixture.md +17 -0
  129. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5a-diff-stat-sem-guarda.fixture.md +17 -0
  130. package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5b-test-f-sobre-diretorio.fixture.md +20 -0
  131. package/scripts/__fixtures__/veto-checks/copy-clean.md +4 -0
  132. package/scripts/__fixtures__/veto-checks/copy-dashes.md +4 -0
  133. package/scripts/__fixtures__/veto-checks/n8n-bad.md +18 -0
  134. package/scripts/__fixtures__/veto-checks/n8n-ok.md +22 -0
  135. package/scripts/__fixtures__/veto-checks/page-bad.html +7 -0
  136. package/scripts/__fixtures__/veto-checks/phash/copy.png +0 -0
  137. package/scripts/__fixtures__/veto-checks/phash/distinct.png +0 -0
  138. package/scripts/__fixtures__/veto-checks/phash/distinct2.png +0 -0
  139. package/scripts/__fixtures__/veto-checks/phash/make-fixtures.cjs +203 -0
  140. package/scripts/__fixtures__/veto-checks/phash/ref.png +0 -0
  141. package/scripts/__fixtures__/veto-checks/slide-ok.html +15 -0
  142. package/scripts/__fixtures__/veto-checks/slide-overflow.html +14 -0
  143. package/scripts/__fixtures__/veto-checks/sweep-pod/agents/vc-checker.md +13 -0
  144. package/scripts/__fixtures__/veto-checks/sweep-pod/templates/check-tmpl.md +6 -0
  145. package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.smoke.json +10 -0
  146. package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.yaml +19 -0
  147. package/scripts/__fixtures__/voz-do-dono/README.md +23 -0
  148. package/scripts/__fixtures__/voz-do-dono/dono-escalar.yaml +9 -0
  149. package/scripts/__fixtures__/voz-do-dono/dono-guia.yaml +10 -0
  150. package/scripts/__fixtures__/voz-do-dono/peca-3a-pessoa.md +6 -0
  151. package/scripts/__fixtures__/voz-do-dono/peca-com-lexico-proibido.md +6 -0
  152. package/scripts/__fixtures__/voz-do-dono/peca-limpa-1a-pessoa.md +6 -0
  153. package/scripts/__tests__/derive-ready-transitions.test.cjs +269 -0
  154. package/scripts/__tests__/enforce-cycle-authority.test.cjs +869 -0
  155. package/scripts/__tests__/enforce-git-push-authority.test.cjs +701 -0
  156. package/scripts/__tests__/enforce-ready-oracles.test.cjs +745 -0
  157. package/scripts/__tests__/motor-scripts.test.cjs +339 -0
  158. package/scripts/__tests__/pc-run-pod-counter.test.cjs +58 -0
  159. package/scripts/__tests__/pc-run-pod.test.cjs +578 -0
  160. package/scripts/__tests__/validate-pod-workflow.test.cjs +90 -0
  161. package/scripts/__tests__/validate-story-acs.test.cjs +607 -0
  162. package/scripts/anti-path.test.cjs +163 -0
  163. package/scripts/arena.cjs +514 -0
  164. package/scripts/arena.test.cjs +213 -0
  165. package/scripts/brief-leitura-obrigatoria.test.cjs +364 -0
  166. package/scripts/consolidate-knowledge-runner.test.cjs +249 -0
  167. package/scripts/default-funcional.test.cjs +153 -0
  168. package/scripts/derive-ready-transitions.cjs +325 -0
  169. package/scripts/forge-additive.test.cjs +158 -0
  170. package/scripts/forge-assess-tier.cjs +205 -0
  171. package/scripts/forge-assess-tier.test.cjs +114 -0
  172. package/scripts/forge-canonical.test.cjs +624 -0
  173. package/scripts/forge-generate.cjs +1303 -0
  174. package/scripts/forge-harden-learning.cjs +921 -0
  175. package/scripts/forge-harden-learning.test.cjs +242 -0
  176. package/scripts/forge-ingest-memory.cjs +136 -0
  177. package/scripts/forge-upgrade-pod.cjs +368 -0
  178. package/scripts/forge.test.cjs +609 -0
  179. package/scripts/harden-knowledge.test.cjs +612 -0
  180. package/scripts/harness-g5-lite.cjs +243 -0
  181. package/scripts/harness-g5-lite.test.cjs +134 -0
  182. package/scripts/hn-carousel-contrato-entrada.test.cjs +96 -0
  183. package/scripts/migrate-squad-orchestration.test.cjs +146 -0
  184. package/scripts/migration-manifest-sf3.2.test.cjs +382 -0
  185. package/scripts/migration-manifest-sf3.3.test.cjs +170 -0
  186. package/scripts/migration-manifest-sf5.5.test.cjs +189 -0
  187. package/scripts/migration-manifest.cjs +1146 -0
  188. package/scripts/migration-manifest.test.cjs +186 -0
  189. package/scripts/npm-scope-invocation.test.cjs +194 -0
  190. package/scripts/owner-layer.cjs +442 -0
  191. package/scripts/owner-layer.test.cjs +358 -0
  192. package/scripts/pc-run-pipeline.cjs +289 -0
  193. package/scripts/pc-run-pipeline.test.cjs +256 -0
  194. package/scripts/pc-run-pod-countgte.test.cjs +66 -0
  195. package/scripts/pc-run-pod.cjs +1355 -0
  196. package/scripts/phash-gate.test.cjs +433 -0
  197. package/scripts/pod-export-compile.cjs +487 -0
  198. package/scripts/pod-export-compile.test.cjs +312 -0
  199. package/scripts/pod-export-executor.cjs +678 -0
  200. package/scripts/pod-export-executor.test.cjs +1341 -0
  201. package/scripts/pod-export-hardening.test.cjs +531 -0
  202. package/scripts/pod-export-postprocess.cjs +427 -0
  203. package/scripts/pod-export-postprocess.test.cjs +558 -0
  204. package/scripts/pod-export-queue-race.test.cjs +865 -0
  205. package/scripts/pod-export-release.cjs +473 -0
  206. package/scripts/pod-export-release.test.cjs +267 -0
  207. package/scripts/pod-export-service.cjs +1297 -0
  208. package/scripts/pod-export-service.test.cjs +489 -0
  209. package/scripts/pod-export-tools.cjs +470 -0
  210. package/scripts/pod-export-ui.cjs +805 -0
  211. package/scripts/pod-export-ui.test.cjs +301 -0
  212. package/scripts/pod-memory-budget.test.cjs +309 -0
  213. package/scripts/pod-memory-note.cjs +357 -0
  214. package/scripts/pod-memory-note.test.cjs +452 -0
  215. package/scripts/pod-memory.cjs +1252 -0
  216. package/scripts/pod-memory.test.cjs +951 -0
  217. package/scripts/render-png.test.cjs +307 -0
  218. package/scripts/smoke-isolation.test.cjs +100 -0
  219. package/scripts/smoke-pod-workflow.cjs +755 -0
  220. package/scripts/smoke-sweep.test.cjs +170 -0
  221. package/scripts/validate-adopt.js +235 -0
  222. package/scripts/validate-branding.js +84 -0
  223. package/scripts/validate-budgets.js +140 -0
  224. package/scripts/validate-fidelity-output.cjs +267 -0
  225. package/scripts/validate-fidelity-output.test.cjs +101 -0
  226. package/scripts/validate-install.js +230 -0
  227. package/scripts/validate-no-clone.cjs +220 -0
  228. package/scripts/validate-no-clone.test.cjs +77 -0
  229. package/scripts/validate-pipeline.cjs +145 -0
  230. package/scripts/validate-pod-workflow.cjs +878 -0
  231. package/scripts/validate-source-audit.cjs +170 -0
  232. package/scripts/validate-source-audit.test.cjs +90 -0
  233. package/scripts/validate-story-acs.cjs +862 -0
  234. package/scripts/validate-update-scope-motor.js +421 -0
  235. package/scripts/veto-checks/html-valid.cjs +92 -0
  236. package/scripts/veto-checks/lexical-check.cjs +62 -0
  237. package/scripts/veto-checks/phash-gate.cjs +589 -0
  238. package/scripts/veto-checks/render-gate.cjs +165 -0
  239. package/scripts/veto-checks/render-png.cjs +358 -0
  240. package/scripts/veto-checks.test.cjs +219 -0
  241. package/scripts/watcher-audit.cjs +178 -0
  242. package/template/.claude/CLAUDE.md +103 -0
  243. package/template/.claude/agents/pc-analyst.md +100 -0
  244. package/template/.claude/agents/pc-architect.md +32 -0
  245. package/template/.claude/agents/pc-dev.md +27 -0
  246. package/template/.claude/agents/pc-devops.md +45 -0
  247. package/template/.claude/agents/pc-planner.md +32 -0
  248. package/template/.claude/agents/pc-po.md +25 -0
  249. package/template/.claude/agents/pc-qa.md +25 -0
  250. package/template/.claude/commands/power/academy.md +9 -0
  251. package/template/.claude/commands/power/automation.md +9 -0
  252. package/template/.claude/commands/power/content-carousel.md +267 -0
  253. package/template/.claude/commands/power/content.md +9 -0
  254. package/template/.claude/commands/power/dev.md +9 -0
  255. package/template/.claude/commands/power/forge.md +224 -0
  256. package/template/.claude/commands/power/hormozi.md +221 -0
  257. package/template/.claude/commands/power/modo.md +57 -0
  258. package/template/.claude/hooks/README.md +114 -0
  259. package/template/.claude/hooks/context-budget.cjs +64 -0
  260. package/template/.claude/hooks/enforce-cycle-authority.cjs +457 -0
  261. package/template/.claude/hooks/enforce-git-push-authority.cjs +925 -0
  262. package/template/.claude/hooks/enforce-ready-oracles.cjs +502 -0
  263. package/template/.claude/rules/authority.md +76 -0
  264. package/template/.claude/rules/curadoria-de-conhecimento.md +30 -0
  265. package/template/.claude/rules/model-matrix.md +34 -0
  266. package/template/.claude/rules/orchestration.md +133 -0
  267. package/template/.claude/settings.json +50 -0
  268. package/template/.claude/skills/pc-apply-qa-fixes/SKILL.md +108 -0
  269. package/template/.claude/skills/pc-apply-qa-fixes/references/fix-loop.md +40 -0
  270. package/template/.claude/skills/pc-apply-qa-fixes/references/fix-request-template.md +70 -0
  271. package/template/.claude/skills/pc-arena/SKILL.md +96 -0
  272. package/template/.claude/skills/pc-close-story/SKILL.md +105 -0
  273. package/template/.claude/skills/pc-commit/SKILL.md +108 -0
  274. package/template/.claude/skills/pc-develop-story/SKILL.md +116 -0
  275. package/template/.claude/skills/pc-full-cycle/SKILL.md +150 -0
  276. package/template/.claude/skills/pc-pipeline/SKILL.md +63 -0
  277. package/template/.claude/skills/pc-pipeline/references/gate-templates.md +46 -0
  278. package/template/.claude/skills/pc-review-story/SKILL.md +129 -0
  279. package/template/.claude/skills/pc-review-story/references/false-positive-detection.md +50 -0
  280. package/template/.claude/skills/pc-review-story/references/nfr-assess.md +47 -0
  281. package/template/.claude/skills/pc-review-story/references/risk-profile.md +75 -0
  282. package/template/.claude/skills/pc-review-story/references/security-checklist.md +69 -0
  283. package/template/.claude/skills/pc-review-story/references/test-design.md +37 -0
  284. package/template/.claude/skills/pc-review-story/references/trace-requirements.md +46 -0
  285. package/template/.claude/skills/pc-run-pod/SKILL.md +123 -0
  286. package/template/.claude/skills/pc-validate-story/SKILL.md +114 -0
  287. package/template/.claude/skills/pc-wave/SKILL.md +133 -0
  288. package/template/.env.example +10 -0
  289. package/template/knowledge/analyst/brainstorming.md +40 -0
  290. package/template/knowledge/analyst/brief-skeleton.md +32 -0
  291. package/template/knowledge/analyst/competitor-skeleton.md +39 -0
  292. package/template/knowledge/analyst/elicitation-menu.md +49 -0
  293. package/template/knowledge/analyst/market-research-skeleton.md +36 -0
  294. package/template/knowledge/analyst/research-prompt-structure.md +48 -0
  295. package/template/knowledge/analyst/roi-skeleton.md +51 -0
  296. package/template/knowledge/voice-dna/README.md +99 -0
  297. package/template/knowledge/voice-dna/voice-dna.example.yaml +157 -0
  298. package/template/pods/README.md +64 -0
  299. package/template/pods/academy/README.md +37 -0
  300. package/template/pods/academy/agents/academy-chief.md +27 -0
  301. package/template/pods/academy/examples/palestra.example.md +142 -0
  302. package/template/pods/academy/pod-spec.json +44 -0
  303. package/template/pods/academy/templates/materiais-tmpl.md +17 -0
  304. package/template/pods/academy/templates/revisao-didatica-tmpl.md +20 -0
  305. package/template/pods/academy/workflows/wf-materiais-revisao.yaml +30 -0
  306. package/template/pods/authority-content/README.md +43 -0
  307. package/template/pods/authority-content/agents/content-chief.md +28 -0
  308. package/template/pods/authority-content/pod-spec.json +45 -0
  309. package/template/pods/authority-content/templates/criacao-na-voz-tmpl.md +17 -0
  310. package/template/pods/authority-content/templates/red-team-factual-tmpl.md +23 -0
  311. package/template/pods/authority-content/workflows/wf-criacao-redteam.yaml +30 -0
  312. package/template/pods/automation/README.md +37 -0
  313. package/template/pods/automation/agents/langgraph-architect.md +30 -0
  314. package/template/pods/automation/agents/n8n-architect.md +30 -0
  315. package/template/pods/automation/examples/README.md +46 -0
  316. package/template/pods/automation/examples/n8n-content-radar.example.json +380 -0
  317. package/template/pods/automation/knowledge/langgraph-patterns.md +126 -0
  318. package/template/pods/automation/knowledge/n8n-patterns.md +131 -0
  319. package/template/pods/automation/memory/README.md +16 -0
  320. package/template/pods/automation/memory/learnings.consolidated.md +8 -0
  321. package/template/pods/automation/memory/learnings.jsonl +0 -0
  322. package/template/pods/automation/pod-spec.json +109 -0
  323. package/template/pods/automation/specs/wf-langgraph-build.spec.json +107 -0
  324. package/template/pods/automation/squad-io.yaml +28 -0
  325. package/template/pods/automation/templates/lg-build-tmpl.md +17 -0
  326. package/template/pods/automation/templates/lg-design-tmpl.md +23 -0
  327. package/template/pods/automation/templates/lg-discover-tmpl.md +20 -0
  328. package/template/pods/automation/templates/lg-handoff-tmpl.md +20 -0
  329. package/template/pods/automation/templates/lg-test-tmpl.md +20 -0
  330. package/template/pods/automation/templates/n8n-build-tmpl.md +14 -0
  331. package/template/pods/automation/templates/n8n-design-tmpl.md +23 -0
  332. package/template/pods/automation/templates/n8n-discover-tmpl.md +20 -0
  333. package/template/pods/automation/templates/n8n-handoff-tmpl.md +20 -0
  334. package/template/pods/automation/templates/n8n-test-tmpl.md +20 -0
  335. package/template/pods/automation/workflows/wf-langgraph-build.smoke.json +11 -0
  336. package/template/pods/automation/workflows/wf-langgraph-build.yaml +64 -0
  337. package/template/pods/automation/workflows/wf-n8n-build.smoke.json +11 -0
  338. package/template/pods/automation/workflows/wf-n8n-build.yaml +65 -0
  339. package/template/pods/content-carousel/README.md +91 -0
  340. package/template/pods/content-carousel/agents/carousel-builder.md +28 -0
  341. package/template/pods/content-carousel/agents/carousel-visual.md +24 -0
  342. package/template/pods/content-carousel/agents/hn-curator.md +74 -0
  343. package/template/pods/content-carousel/config/heuristic-watcher-rubric.yaml +59 -0
  344. package/template/pods/content-carousel/knowledge/aquisicao-ancora.md +443 -0
  345. package/template/pods/content-carousel/knowledge/cta-brief.md +25 -0
  346. package/template/pods/content-carousel/knowledge/dono.example.yaml +45 -0
  347. package/template/pods/content-carousel/knowledge/identidade-visual-mascote.md +62 -0
  348. package/template/pods/content-carousel/knowledge/image-generation.md +62 -0
  349. package/template/pods/content-carousel/knowledge/selecao-de-ancora.md +60 -0
  350. package/template/pods/content-carousel/knowledge/slides-html.md +56 -0
  351. package/template/pods/content-carousel/memory/README.md +18 -0
  352. package/template/pods/content-carousel/memory/learnings.consolidated.md +6 -0
  353. package/template/pods/content-carousel/memory/learnings.jsonl +0 -0
  354. package/template/pods/content-carousel/pod-spec.json +100 -0
  355. package/template/pods/content-carousel/squad-io.yaml +10 -0
  356. package/template/pods/content-carousel/templates/assembly-tmpl.md +23 -0
  357. package/template/pods/content-carousel/templates/digest-tmpl.md +29 -0
  358. package/template/pods/content-carousel/templates/visuals-tmpl.md +20 -0
  359. package/template/pods/content-carousel/workflows/wf-content-carousel.smoke.json +23 -0
  360. package/template/pods/content-carousel/workflows/wf-content-carousel.yaml +80 -0
  361. package/template/pods/dev-ia/README.md +45 -0
  362. package/template/pods/dev-ia/agents/db-architect.md +33 -0
  363. package/template/pods/dev-ia/agents/ux-architect.md +29 -0
  364. package/template/pods/dev-ia/knowledge/db/migration-protocol.md +95 -0
  365. package/template/pods/dev-ia/knowledge/db/rls-patterns.md +101 -0
  366. package/template/pods/dev-ia/knowledge/db/schema-review-checklist.md +76 -0
  367. package/template/pods/dev-ia/memory/README.md +16 -0
  368. package/template/pods/dev-ia/memory/learnings.consolidated.md +8 -0
  369. package/template/pods/dev-ia/memory/learnings.jsonl +0 -0
  370. package/template/pods/dev-ia/pod-spec.json +34 -0
  371. package/template/pods/dev-ia/templates/schema-review-tmpl.md +23 -0
  372. package/template/pods/dev-ia/templates/ux-flow-review-tmpl.md +23 -0
  373. package/template/pods/dev-ia/tools/db-ops/backup-manager.sh +321 -0
  374. package/template/pods/dev-ia/tools/db-ops/best-practices-auditor.sh +534 -0
  375. package/template/pods/dev-ia/tools/db-ops/bootstrap-runner.sh +255 -0
  376. package/template/pods/dev-ia/tools/db-ops/data-loader.sh +616 -0
  377. package/template/pods/dev-ia/tools/db-ops/detect-database.sh +113 -0
  378. package/template/pods/dev-ia/tools/db-ops/explain-analyzer.sh +285 -0
  379. package/template/pods/dev-ia/tools/db-ops/health-checker.sh +323 -0
  380. package/template/pods/dev-ia/tools/db-ops/migration-runner.sh +308 -0
  381. package/template/pods/dev-ia/tools/db-ops/postgresql-schema-loader.sh +334 -0
  382. package/template/pods/dev-ia/tools/db-ops/query-runner.sh +171 -0
  383. package/template/pods/dev-ia/tools/db-ops/rls-policy-installer.sh +480 -0
  384. package/template/pods/dev-ia/tools/db-ops/rls-test-suite.sh +172 -0
  385. package/template/pods/dev-ia/tools/db-ops/schema-context-loader.sh +176 -0
  386. package/template/pods/hormozi-method/README.md +52 -0
  387. package/template/pods/hormozi-method/agents/acquisition-strategist.md +33 -0
  388. package/template/pods/hormozi-method/agents/conversion-copywriter.md +34 -0
  389. package/template/pods/hormozi-method/agents/monetization-architect.md +35 -0
  390. package/template/pods/hormozi-method/agents/offer-engineer.md +37 -0
  391. package/template/pods/hormozi-method/knowledge/core-four-leads.md +51 -0
  392. package/template/pods/hormozi-method/knowledge/grand-slam-offer.md +66 -0
  393. package/template/pods/hormozi-method/knowledge/growth-decision.md +38 -0
  394. package/template/pods/hormozi-method/knowledge/hooks-and-ads.md +56 -0
  395. package/template/pods/hormozi-method/knowledge/launch-email.md +31 -0
  396. package/template/pods/hormozi-method/knowledge/money-model.md +46 -0
  397. package/template/pods/hormozi-method/knowledge/opportunity-screening.md +44 -0
  398. package/template/pods/hormozi-method/knowledge/pages.md +25 -0
  399. package/template/pods/hormozi-method/knowledge/pos-lancamento-leads.md +56 -0
  400. package/template/pods/hormozi-method/knowledge/pricing.md +36 -0
  401. package/template/pods/hormozi-method/knowledge/retention-ltv.md +37 -0
  402. package/template/pods/hormozi-method/knowledge/scale-roadmap.md +35 -0
  403. package/template/pods/hormozi-method/knowledge/swipefiles-curados.md +44 -0
  404. package/template/pods/hormozi-method/knowledge/value-equation-diagnostic.md +77 -0
  405. package/template/pods/hormozi-method/memory/README.md +16 -0
  406. package/template/pods/hormozi-method/memory/learnings.consolidated.md +6 -0
  407. package/template/pods/hormozi-method/memory/learnings.jsonl +0 -0
  408. package/template/pods/hormozi-method/pod-spec.json +50 -0
  409. package/template/pods/hormozi-method/specs/wf-full-launch-sequence.spec.json +149 -0
  410. package/template/pods/hormozi-method/specs/wf-lead-magnet-pipeline.spec.json +125 -0
  411. package/template/pods/hormozi-method/specs/wf-money-model-design.spec.json +117 -0
  412. package/template/pods/hormozi-method/specs/wf-paid-ads-campaign.spec.json +132 -0
  413. package/template/pods/hormozi-method/specs/wf-scaling-diagnostic.spec.json +121 -0
  414. package/template/pods/hormozi-method/squad-io.yaml +43 -0
  415. package/template/pods/hormozi-method/templates/conversion-copywriter-tmpl.md +20 -0
  416. package/template/pods/hormozi-method/templates/launch-execucao-tmpl.md +17 -0
  417. package/template/pods/hormozi-method/templates/launch-fechamento-tmpl.md +17 -0
  418. package/template/pods/hormozi-method/templates/launch-pos-tmpl.md +17 -0
  419. package/template/pods/hormozi-method/templates/launch-preparacao-tmpl.md +17 -0
  420. package/template/pods/hormozi-method/templates/lm-copy-tmpl.md +17 -0
  421. package/template/pods/hormozi-method/templates/lm-distribuicao-tmpl.md +18 -0
  422. package/template/pods/hormozi-method/templates/lm-estrategia-tmpl.md +17 -0
  423. package/template/pods/hormozi-method/templates/mm-arquitetura-tmpl.md +18 -0
  424. package/template/pods/hormozi-method/templates/mm-copy-tmpl.md +17 -0
  425. package/template/pods/hormozi-method/templates/mm-diagnostico-tmpl.md +14 -0
  426. package/template/pods/hormozi-method/templates/monetization-architect-tmpl.md +17 -0
  427. package/template/pods/hormozi-method/templates/offer-engineer-tmpl.md +20 -0
  428. package/template/pods/hormozi-method/templates/paid-criativos-tmpl.md +19 -0
  429. package/template/pods/hormozi-method/templates/paid-fundacao-tmpl.md +17 -0
  430. package/template/pods/hormozi-method/templates/paid-teste-escala-tmpl.md +17 -0
  431. package/template/pods/hormozi-method/templates/scaling-diagnostico-tmpl.md +17 -0
  432. package/template/pods/hormozi-method/templates/scaling-priorizacao-tmpl.md +17 -0
  433. package/template/pods/hormozi-method/templates/scaling-roadmap-tmpl.md +17 -0
  434. package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.smoke.json +12 -0
  435. package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.yaml +56 -0
  436. package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.smoke.json +11 -0
  437. package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.yaml +45 -0
  438. package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.smoke.json +9 -0
  439. package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.yaml +45 -0
  440. package/template/pods/hormozi-method/workflows/wf-money-model-design.smoke.json +11 -0
  441. package/template/pods/hormozi-method/workflows/wf-money-model-design.yaml +45 -0
  442. package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.smoke.json +9 -0
  443. package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.yaml +46 -0
  444. package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.smoke.json +11 -0
  445. package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.yaml +44 -0
  446. package/template/pods/squad-forge/README.md +53 -0
  447. package/template/pods/squad-forge/agents/forge-chief.md +31 -0
  448. package/template/pods/squad-forge/agents/mind-extractor.md +29 -0
  449. package/template/pods/squad-forge/agents/pod-critic.md +26 -0
  450. package/template/pods/squad-forge/config/heuristic-watcher-rubric.yaml +74 -0
  451. package/template/pods/squad-forge/knowledge/fidelity-rubric.yaml +176 -0
  452. package/template/pods/squad-forge/knowledge/g6-memory-check.md +17 -0
  453. package/template/pods/squad-forge/knowledge/memory-ingest.md +16 -0
  454. package/template/pods/squad-forge/knowledge/source-audit-rubric.yaml +60 -0
  455. package/template/pods/squad-forge/memory/README.md +16 -0
  456. package/template/pods/squad-forge/memory/learnings.consolidated.md +8 -0
  457. package/template/pods/squad-forge/memory/learnings.jsonl +0 -0
  458. package/template/pods/squad-forge/pod-spec.json +166 -0
  459. package/template/pods/squad-forge/squad-io.yaml +13 -0
  460. package/template/pods/squad-forge/tasks/pipeline.md +158 -0
  461. package/template/pods/squad-forge/templates/discovery-tmpl.md +40 -0
  462. package/template/pods/squad-forge/templates/generation-tmpl.md +18 -0
  463. package/template/pods/squad-forge/templates/red-team-tmpl.md +17 -0
  464. package/template/pods/squad-forge/templates/register-tmpl.md +17 -0
  465. package/template/pods/squad-forge/templates/workflow-tmpl.yaml +101 -0
  466. package/template/pods/squad-forge/workflows/wf-forge.smoke.json +12 -0
  467. package/template/pods/squad-forge/workflows/wf-forge.yaml +60 -0
@@ -0,0 +1,616 @@
1
+ #!/usr/bin/env bash
2
+ # =============================================================================
3
+ # data-loader.sh - CSV and Seed Loader (Worker Script)
4
+ # =============================================================================
5
+ # execution_type: Worker
6
+ # pattern: EXEC-W-001
7
+ # tasks: db-load-csv, db-seed
8
+ # token_savings: 88%
9
+ # =============================================================================
10
+
11
+ set -euo pipefail
12
+
13
+ # Colors
14
+ RED='\033[0;31m'
15
+ GREEN='\033[0;32m'
16
+ YELLOW='\033[1;33m'
17
+ BLUE='\033[0;34m'
18
+ NC='\033[0m'
19
+
20
+ # Defaults
21
+ DB_URL=""
22
+ DRY_RUN=false
23
+ VALIDATE=false
24
+ VERBOSE=false
25
+ DELIMITER=","
26
+ IMPORT_MODE="safe"
27
+ ENVIRONMENT=""
28
+ MODE=""
29
+ TABLE_REF=""
30
+ DATA_FILE=""
31
+ SEED_FILE=""
32
+ TABLE_SCHEMA="public"
33
+ TABLE_NAME=""
34
+ QUALIFIED_TABLE=""
35
+ QUALIFIED_STAGING=""
36
+
37
+ declare -a TEMP_FILES=()
38
+ declare -a HEADER_COLUMNS=()
39
+ declare -a PRIMARY_KEY_COLUMNS=()
40
+ declare -a NON_PRIMARY_COLUMNS=()
41
+
42
+ usage() {
43
+ cat << EOF
44
+ Usage:
45
+ $(basename "$0") [OPTIONS] <table> <csv_file>
46
+ $(basename "$0") [OPTIONS] --seed <sql_file>
47
+ $(basename "$0") [OPTIONS] <sql_file>
48
+
49
+ Load CSV data into PostgreSQL/Supabase or apply seed SQL safely.
50
+
51
+ CSV OPTIONS:
52
+ --mode <safe|fast|upsert> Import strategy (default: safe)
53
+ --delimiter <char> CSV delimiter (default: ,)
54
+
55
+ SEED OPTIONS:
56
+ --seed <path> Treat input as seed SQL file
57
+ --env <name> Label target environment for logging
58
+
59
+ COMMON OPTIONS:
60
+ --dry-run Execute inside rollback
61
+ --validate Run extra safety validation before execution
62
+ -v, --verbose Verbose output
63
+ -h, --help Show this help
64
+
65
+ EXAMPLES:
66
+ $(basename "$0") users data/users.csv
67
+ $(basename "$0") users data/users.csv --delimiter '|'
68
+ $(basename "$0") users data/users.csv --dry-run
69
+ $(basename "$0") --seed supabase/seeds/dev.sql
70
+ $(basename "$0") supabase/seeds/dev.sql --validate --dry-run
71
+
72
+ ENVIRONMENT:
73
+ SUPABASE_DB_URL or DATABASE_URL Required. PostgreSQL connection string.
74
+ EOF
75
+ }
76
+
77
+ log_info() { echo -e "${BLUE}ℹ${NC} $1"; }
78
+ log_success() { echo -e "${GREEN}✓${NC} $1"; }
79
+ log_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
80
+ log_error() { echo -e "${RED}✗${NC} $1"; }
81
+
82
+ cleanup() {
83
+ local file
84
+ for file in "${TEMP_FILES[@]}"; do
85
+ [[ -e "$file" ]] && rm -f "$file"
86
+ done
87
+ }
88
+
89
+ trap cleanup EXIT
90
+
91
+ register_temp_file() {
92
+ TEMP_FILES+=("$1")
93
+ }
94
+
95
+ escape_sql_literal() {
96
+ printf '%s' "$1" | sed "s/'/''/g"
97
+ }
98
+
99
+ quote_ident() {
100
+ printf '"%s"' "$1"
101
+ }
102
+
103
+ join_sql_list() {
104
+ local joined=""
105
+ local item
106
+ for item in "$@"; do
107
+ if [[ -n "$joined" ]]; then
108
+ joined+=", "
109
+ fi
110
+ joined+="$item"
111
+ done
112
+ printf '%s' "$joined"
113
+ }
114
+
115
+ quoted_identifier_list() {
116
+ local quoted_columns=()
117
+ local column
118
+ for column in "$@"; do
119
+ quoted_columns+=("$(quote_ident "$column")")
120
+ done
121
+ join_sql_list "${quoted_columns[@]}"
122
+ }
123
+
124
+ array_contains() {
125
+ local needle="$1"
126
+ shift
127
+ local item
128
+ for item in "$@"; do
129
+ [[ "$item" == "$needle" ]] && return 0
130
+ done
131
+ return 1
132
+ }
133
+
134
+ check_env() {
135
+ DB_URL="${SUPABASE_DB_URL:-${DATABASE_URL:-}}"
136
+ if [[ -z "$DB_URL" ]]; then
137
+ log_error "SUPABASE_DB_URL or DATABASE_URL not set"
138
+ exit 1
139
+ fi
140
+ }
141
+
142
+ validate_identifier() {
143
+ local value="$1"
144
+ if [[ ! "$value" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
145
+ log_error "Invalid SQL identifier: $value"
146
+ exit 1
147
+ fi
148
+ }
149
+
150
+ resolve_table_reference() {
151
+ TABLE_SCHEMA="public"
152
+ TABLE_NAME="$1"
153
+
154
+ if [[ "$1" == *.* ]]; then
155
+ TABLE_SCHEMA="${1%%.*}"
156
+ TABLE_NAME="${1##*.}"
157
+ fi
158
+
159
+ validate_identifier "$TABLE_SCHEMA"
160
+ validate_identifier "$TABLE_NAME"
161
+ QUALIFIED_TABLE="$(quote_ident "$TABLE_SCHEMA").$(quote_ident "$TABLE_NAME")"
162
+ }
163
+
164
+ resolve_absolute_path() {
165
+ local input_path="$1"
166
+ if [[ "$input_path" = /* ]]; then
167
+ printf '%s' "$input_path"
168
+ else
169
+ printf '%s/%s' "$(pwd)" "$input_path"
170
+ fi
171
+ }
172
+
173
+ collect_header_columns() {
174
+ local header_line raw_column column
175
+
176
+ header_line=$(head -n 1 "$DATA_FILE" | tr -d '\r')
177
+ if [[ -z "$header_line" ]]; then
178
+ log_error "CSV header is empty: $DATA_FILE"
179
+ exit 1
180
+ fi
181
+
182
+ HEADER_COLUMNS=()
183
+ IFS="$DELIMITER" read -r -a raw_columns <<< "$header_line"
184
+
185
+ for raw_column in "${raw_columns[@]}"; do
186
+ column=$(printf '%s' "$raw_column" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
187
+ column="${column#\"}"
188
+ column="${column%\"}"
189
+ validate_identifier "$column"
190
+ HEADER_COLUMNS+=("$column")
191
+ done
192
+
193
+ if [[ "${#HEADER_COLUMNS[@]}" -eq 0 ]]; then
194
+ log_error "No columns detected in CSV header"
195
+ exit 1
196
+ fi
197
+ }
198
+
199
+ load_primary_key_columns() {
200
+ PRIMARY_KEY_COLUMNS=()
201
+
202
+ while IFS= read -r column; do
203
+ [[ -n "$column" ]] && PRIMARY_KEY_COLUMNS+=("$column")
204
+ done < <(
205
+ psql "$DB_URL" -t -A <<SQL
206
+ SELECT a.attname
207
+ FROM pg_index i
208
+ JOIN pg_class c ON c.oid = i.indrelid
209
+ JOIN pg_namespace n ON n.oid = c.relnamespace
210
+ JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(i.indkey)
211
+ WHERE i.indisprimary
212
+ AND n.nspname = '$TABLE_SCHEMA'
213
+ AND c.relname = '$TABLE_NAME'
214
+ ORDER BY array_position(i.indkey, a.attnum);
215
+ SQL
216
+ )
217
+ }
218
+
219
+ validate_table_exists() {
220
+ local exists
221
+ exists=$(psql "$DB_URL" -t -A <<SQL
222
+ SELECT EXISTS (
223
+ SELECT 1
224
+ FROM information_schema.tables
225
+ WHERE table_schema = '$TABLE_SCHEMA'
226
+ AND table_name = '$TABLE_NAME'
227
+ );
228
+ SQL
229
+ )
230
+
231
+ if [[ "$exists" != "t" ]]; then
232
+ log_error "Table not found: $TABLE_SCHEMA.$TABLE_NAME"
233
+ exit 1
234
+ fi
235
+ }
236
+
237
+ validate_csv_inputs() {
238
+ local available_columns missing_columns="" column
239
+
240
+ if [[ ! -f "$DATA_FILE" ]]; then
241
+ log_error "CSV file not found: $DATA_FILE"
242
+ exit 1
243
+ fi
244
+
245
+ validate_table_exists
246
+ collect_header_columns
247
+
248
+ available_columns=$(psql "$DB_URL" -t -A <<SQL
249
+ SELECT column_name
250
+ FROM information_schema.columns
251
+ WHERE table_schema = '$TABLE_SCHEMA'
252
+ AND table_name = '$TABLE_NAME'
253
+ ORDER BY ordinal_position;
254
+ SQL
255
+ )
256
+
257
+ for column in "${HEADER_COLUMNS[@]}"; do
258
+ if ! printf '%s\n' "$available_columns" | grep -Fxq "$column"; then
259
+ if [[ -n "$missing_columns" ]]; then
260
+ missing_columns+=", "
261
+ fi
262
+ missing_columns+="$column"
263
+ fi
264
+ done
265
+
266
+ if [[ -n "$missing_columns" ]]; then
267
+ log_error "CSV columns not found in $TABLE_SCHEMA.$TABLE_NAME: $missing_columns"
268
+ exit 1
269
+ fi
270
+ }
271
+
272
+ build_column_lists() {
273
+ local column quoted_columns=()
274
+
275
+ for column in "${HEADER_COLUMNS[@]}"; do
276
+ quoted_columns+=("$(quote_ident "$column")")
277
+ done
278
+ COLUMN_LIST_SQL=$(join_sql_list "${quoted_columns[@]}")
279
+
280
+ NON_PRIMARY_COLUMNS=()
281
+ for column in "${HEADER_COLUMNS[@]}"; do
282
+ if ! array_contains "$column" "${PRIMARY_KEY_COLUMNS[@]}"; then
283
+ NON_PRIMARY_COLUMNS+=("$column")
284
+ fi
285
+ done
286
+ }
287
+
288
+ build_merge_sql() {
289
+ local conflict_columns=()
290
+ local update_assignments=()
291
+ local column primary_key_present=true
292
+
293
+ if [[ "${#PRIMARY_KEY_COLUMNS[@]}" -eq 0 ]]; then
294
+ log_warning "No primary key detected; falling back to INSERT"
295
+ printf 'INSERT INTO %s (%s) SELECT %s FROM %s' \
296
+ "$QUALIFIED_TABLE" "$COLUMN_LIST_SQL" "$COLUMN_LIST_SQL" "$QUALIFIED_STAGING"
297
+ return
298
+ fi
299
+
300
+ for column in "${PRIMARY_KEY_COLUMNS[@]}"; do
301
+ if ! array_contains "$column" "${HEADER_COLUMNS[@]}"; then
302
+ primary_key_present=false
303
+ break
304
+ fi
305
+ conflict_columns+=("$(quote_ident "$column")")
306
+ done
307
+
308
+ if [[ "$primary_key_present" != true ]]; then
309
+ log_warning "CSV payload does not include the full primary key; falling back to INSERT"
310
+ printf 'INSERT INTO %s (%s) SELECT %s FROM %s' \
311
+ "$QUALIFIED_TABLE" "$COLUMN_LIST_SQL" "$COLUMN_LIST_SQL" "$QUALIFIED_STAGING"
312
+ return
313
+ fi
314
+
315
+ if [[ "${#NON_PRIMARY_COLUMNS[@]}" -eq 0 ]]; then
316
+ printf 'INSERT INTO %s (%s) SELECT %s FROM %s ON CONFLICT (%s) DO NOTHING' \
317
+ "$QUALIFIED_TABLE" \
318
+ "$COLUMN_LIST_SQL" \
319
+ "$COLUMN_LIST_SQL" \
320
+ "$QUALIFIED_STAGING" \
321
+ "$(join_sql_list "${conflict_columns[@]}")"
322
+ return
323
+ fi
324
+
325
+ for column in "${NON_PRIMARY_COLUMNS[@]}"; do
326
+ update_assignments+=("$(quote_ident "$column") = EXCLUDED.$(quote_ident "$column")")
327
+ done
328
+
329
+ printf 'INSERT INTO %s (%s) SELECT %s FROM %s ON CONFLICT (%s) DO UPDATE SET %s' \
330
+ "$QUALIFIED_TABLE" \
331
+ "$COLUMN_LIST_SQL" \
332
+ "$COLUMN_LIST_SQL" \
333
+ "$QUALIFIED_STAGING" \
334
+ "$(join_sql_list "${conflict_columns[@]}")" \
335
+ "$(join_sql_list "${update_assignments[@]}")"
336
+ }
337
+
338
+ write_csv_sql_file() {
339
+ local sql_file="$1"
340
+ local absolute_file escaped_file escaped_delimiter merge_sql
341
+
342
+ absolute_file=$(resolve_absolute_path "$DATA_FILE")
343
+ escaped_file=$(escape_sql_literal "$absolute_file")
344
+ escaped_delimiter=$(escape_sql_literal "$DELIMITER")
345
+
346
+ if [[ "$IMPORT_MODE" == "fast" ]]; then
347
+ {
348
+ echo "BEGIN;"
349
+ printf "\\copy %s (%s) FROM '%s' WITH (FORMAT csv, HEADER true, DELIMITER '%s')\n" \
350
+ "$QUALIFIED_TABLE" "$COLUMN_LIST_SQL" "$escaped_file" "$escaped_delimiter"
351
+ printf "SELECT COUNT(*) AS target_rows_after FROM %s;\n" "$QUALIFIED_TABLE"
352
+ if $DRY_RUN; then
353
+ echo "ROLLBACK;"
354
+ else
355
+ echo "COMMIT;"
356
+ fi
357
+ } > "$sql_file"
358
+ return
359
+ fi
360
+
361
+ STAGING_TABLE="_db_ops_${TABLE_NAME}_$$"
362
+ QUALIFIED_STAGING="$(quote_ident "$STAGING_TABLE")"
363
+ merge_sql=$(build_merge_sql)
364
+
365
+ {
366
+ echo "BEGIN;"
367
+ printf "CREATE TEMP TABLE %s (LIKE %s INCLUDING ALL) ON COMMIT DROP;\n" \
368
+ "$QUALIFIED_STAGING" "$QUALIFIED_TABLE"
369
+ printf "\\copy %s (%s) FROM '%s' WITH (FORMAT csv, HEADER true, DELIMITER '%s')\n" \
370
+ "$QUALIFIED_STAGING" "$COLUMN_LIST_SQL" "$escaped_file" "$escaped_delimiter"
371
+ printf "SELECT COUNT(*) AS staged_rows FROM %s;\n" "$QUALIFIED_STAGING"
372
+
373
+ if [[ "${#PRIMARY_KEY_COLUMNS[@]}" -gt 0 ]]; then
374
+ local pk_list_sql
375
+ pk_list_sql=$(quoted_identifier_list "${PRIMARY_KEY_COLUMNS[@]}")
376
+ printf "DO \$\$\nBEGIN\n"
377
+ printf " IF EXISTS (\n"
378
+ printf " SELECT 1\n"
379
+ printf " FROM (\n"
380
+ printf " SELECT %s\n" "$pk_list_sql"
381
+ printf " FROM %s\n" "$QUALIFIED_STAGING"
382
+ printf " GROUP BY %s\n" "$pk_list_sql"
383
+ printf " HAVING COUNT(*) > 1\n"
384
+ printf " ) duplicated_keys\n"
385
+ printf " ) THEN\n"
386
+ printf " RAISE EXCEPTION 'Duplicate primary key rows detected in CSV payload';\n"
387
+ printf " END IF;\n"
388
+ printf "END\n\$\$;\n"
389
+ fi
390
+
391
+ printf "%s;\n" "$merge_sql"
392
+ printf "SELECT COUNT(*) AS target_rows_after FROM %s;\n" "$QUALIFIED_TABLE"
393
+ if $DRY_RUN; then
394
+ echo "ROLLBACK;"
395
+ else
396
+ echo "COMMIT;"
397
+ fi
398
+ } > "$sql_file"
399
+ }
400
+
401
+ run_csv_import() {
402
+ local sql_file
403
+ local line_count
404
+
405
+ if [[ "${#DELIMITER}" -ne 1 ]]; then
406
+ log_error "Delimiter must be a single character"
407
+ exit 1
408
+ fi
409
+
410
+ if $VALIDATE; then
411
+ IMPORT_MODE="safe"
412
+ fi
413
+
414
+ case "$IMPORT_MODE" in
415
+ safe|fast|upsert) ;;
416
+ *)
417
+ log_error "Invalid import mode: $IMPORT_MODE"
418
+ exit 1
419
+ ;;
420
+ esac
421
+
422
+ resolve_table_reference "$TABLE_REF"
423
+ validate_csv_inputs
424
+ load_primary_key_columns
425
+ build_column_lists
426
+
427
+ line_count=$(wc -l < "$DATA_FILE" | tr -d ' ')
428
+
429
+ log_info "CSV file: $DATA_FILE"
430
+ log_info "Target table: $TABLE_SCHEMA.$TABLE_NAME"
431
+ log_info "Mode: $IMPORT_MODE"
432
+ log_info "Header columns: $(join_sql_list "${HEADER_COLUMNS[@]}")"
433
+ log_info "CSV rows (including header): $line_count"
434
+
435
+ sql_file=$(mktemp "/tmp/db-ops-data-loader-XXXXXX.sql")
436
+ register_temp_file "$sql_file"
437
+ write_csv_sql_file "$sql_file"
438
+
439
+ psql "$DB_URL" -v ON_ERROR_STOP=1 -f "$sql_file"
440
+
441
+ if $DRY_RUN; then
442
+ log_warning "Dry-run complete. Changes were rolled back."
443
+ else
444
+ log_success "CSV load completed."
445
+ fi
446
+ }
447
+
448
+ seed_has_explicit_transaction() {
449
+ grep -Eiq '^[[:space:]]*(BEGIN|START[[:space:]]+TRANSACTION|COMMIT|ROLLBACK)\b' "$SEED_FILE"
450
+ }
451
+
452
+ validate_seed_inputs() {
453
+ if [[ ! -f "$SEED_FILE" ]]; then
454
+ log_error "Seed file not found: $SEED_FILE"
455
+ exit 1
456
+ fi
457
+
458
+ if $VALIDATE; then
459
+ if grep -Eiq '(^|[^A-Z_])(TRUNCATE|DELETE[[:space:]]+FROM)\b' "$SEED_FILE"; then
460
+ log_error "Seed validation failed: destructive statements detected"
461
+ exit 1
462
+ fi
463
+
464
+ if ! grep -Eiq 'ON[[:space:]]+CONFLICT|WHERE[[:space:]]+NOT[[:space:]]+EXISTS|MERGE[[:space:]]+INTO' "$SEED_FILE"; then
465
+ log_warning "Seed file does not advertise an idempotent pattern (ON CONFLICT / WHERE NOT EXISTS / MERGE)"
466
+ else
467
+ log_success "Seed file exposes an idempotent pattern"
468
+ fi
469
+ fi
470
+ }
471
+
472
+ run_seed() {
473
+ local sql_file
474
+
475
+ validate_seed_inputs
476
+
477
+ log_info "Seed file: $SEED_FILE"
478
+ if [[ -n "$ENVIRONMENT" ]]; then
479
+ log_info "Target environment: $ENVIRONMENT"
480
+ fi
481
+ if [[ "$ENVIRONMENT" == "production" || "$ENVIRONMENT" == "prod" ]]; then
482
+ log_warning "Production seed requested. Ensure this was explicit."
483
+ fi
484
+
485
+ if seed_has_explicit_transaction; then
486
+ if $DRY_RUN; then
487
+ log_error "Dry-run is not supported when the seed file manages its own transaction"
488
+ exit 1
489
+ fi
490
+ psql "$DB_URL" -v ON_ERROR_STOP=1 -f "$SEED_FILE"
491
+ log_success "Seed applied."
492
+ return
493
+ fi
494
+
495
+ sql_file=$(mktemp "/tmp/db-ops-seed-loader-XXXXXX.sql")
496
+ register_temp_file "$sql_file"
497
+
498
+ {
499
+ echo "BEGIN;"
500
+ cat "$SEED_FILE"
501
+ if $DRY_RUN; then
502
+ echo "ROLLBACK;"
503
+ else
504
+ echo "COMMIT;"
505
+ fi
506
+ } > "$sql_file"
507
+
508
+ psql "$DB_URL" -v ON_ERROR_STOP=1 -f "$sql_file"
509
+
510
+ if $DRY_RUN; then
511
+ log_warning "Dry-run complete. Seed changes were rolled back."
512
+ else
513
+ log_success "Seed applied."
514
+ fi
515
+ }
516
+
517
+ parse_args() {
518
+ local positional=()
519
+
520
+ while [[ $# -gt 0 ]]; do
521
+ case "$1" in
522
+ --seed)
523
+ SEED_FILE="${2:-}"
524
+ MODE="seed"
525
+ shift 2
526
+ ;;
527
+ --delimiter)
528
+ DELIMITER="${2:-}"
529
+ shift 2
530
+ ;;
531
+ --mode)
532
+ IMPORT_MODE="${2:-}"
533
+ shift 2
534
+ ;;
535
+ --env)
536
+ ENVIRONMENT="${2:-}"
537
+ shift 2
538
+ ;;
539
+ --dry-run)
540
+ DRY_RUN=true
541
+ shift
542
+ ;;
543
+ --validate)
544
+ VALIDATE=true
545
+ shift
546
+ ;;
547
+ -v|--verbose)
548
+ VERBOSE=true
549
+ shift
550
+ ;;
551
+ -h|--help)
552
+ usage
553
+ exit 0
554
+ ;;
555
+ --)
556
+ shift
557
+ while [[ $# -gt 0 ]]; do
558
+ positional+=("$1")
559
+ shift
560
+ done
561
+ ;;
562
+ *)
563
+ positional+=("$1")
564
+ shift
565
+ ;;
566
+ esac
567
+ done
568
+
569
+ if [[ -n "$SEED_FILE" ]]; then
570
+ if [[ "${#positional[@]}" -gt 0 ]]; then
571
+ log_error "Unexpected positional arguments after --seed"
572
+ exit 1
573
+ fi
574
+ return
575
+ fi
576
+
577
+ if [[ "${#positional[@]}" -eq 1 ]]; then
578
+ if [[ -f "${positional[0]}" ]]; then
579
+ MODE="seed"
580
+ SEED_FILE="${positional[0]}"
581
+ return
582
+ fi
583
+ log_error "Single positional argument must be a seed file path"
584
+ exit 1
585
+ fi
586
+
587
+ if [[ "${#positional[@]}" -eq 2 ]]; then
588
+ MODE="csv"
589
+ TABLE_REF="${positional[0]}"
590
+ DATA_FILE="${positional[1]}"
591
+ return
592
+ fi
593
+
594
+ usage
595
+ exit 1
596
+ }
597
+
598
+ main() {
599
+ parse_args "$@"
600
+ check_env
601
+
602
+ case "$MODE" in
603
+ csv)
604
+ run_csv_import
605
+ ;;
606
+ seed)
607
+ run_seed
608
+ ;;
609
+ *)
610
+ usage
611
+ exit 1
612
+ ;;
613
+ esac
614
+ }
615
+
616
+ main "$@"