@polymorphism-tech/morph-spec 9.8.0 → 10.1.1

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 (202) hide show
  1. package/CLAUDE.md +12 -10
  2. package/README.md +4 -4
  3. package/bin/morph-spec.js +40 -43
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +28 -36
  6. package/docs/QUICKSTART.md +31 -191
  7. package/framework/CLAUDE.md +24 -30
  8. package/framework/MORPH.md +47 -123
  9. package/framework/agents.json +6 -374
  10. package/framework/commands/morph-apply.md +1 -1
  11. package/framework/commands/morph-archive.md +4 -3
  12. package/framework/commands/morph-hotfix.md +8 -30
  13. package/framework/commands/morph-infra.md +2 -2
  14. package/framework/commands/morph-media.md +10 -9
  15. package/framework/commands/morph-preflight.md +3 -3
  16. package/framework/commands/morph-review.md +15 -0
  17. package/framework/commands/morph-status.md +1 -1
  18. package/framework/docs/CLI.md +84 -95
  19. package/framework/evals/review-checklist.md +45 -53
  20. package/framework/hooks/README.md +4 -4
  21. package/framework/hooks/claude-code/core/README.md +1 -1
  22. package/framework/hooks/claude-code/core/denylist.json +4 -4
  23. package/framework/hooks/claude-code/core/gate-guard.js +9 -0
  24. package/framework/hooks/claude-code/core/masked-exit.js +49 -0
  25. package/framework/hooks/claude-code/core/state-sync.js +4 -1
  26. package/framework/hooks/claude-code/core/telemetry-log.js +1 -2
  27. package/framework/hooks/claude-code/core/test-budget.js +10 -70
  28. package/framework/hooks/claude-code/core/validate-completion.js +11 -24
  29. package/framework/hooks/claude-code/core/worktree-context.js +5 -22
  30. package/framework/hooks/claude-code/core/worktree-create.js +6 -45
  31. package/framework/hooks/claude-code/core/worktree-env-inject.js +2 -10
  32. package/framework/hooks/shared/e2e-check.js +0 -0
  33. package/framework/hooks/shared/gate-event.js +2 -2
  34. package/framework/hooks/shared/graph-refresh.js +20 -3
  35. package/framework/hooks/shared/heavy-command.js +32 -1
  36. package/framework/hooks/shared/heavy-config.js +1 -1
  37. package/framework/hooks/shared/next-step.js +63 -24
  38. package/framework/hooks/shared/phase-utils.js +6 -9
  39. package/framework/hooks/shared/report-progress.js +86 -0
  40. package/framework/hooks/shared/state-reader.js +3 -2
  41. package/framework/hooks/statusline.js +332 -0
  42. package/framework/mcp/registry.json +4 -4
  43. package/framework/phases.json +32 -10
  44. package/framework/rules/ai-agents-standards.md +10 -2
  45. package/framework/rules/csharp-standards.md +4 -0
  46. package/framework/rules/data-standards.md +1 -1
  47. package/framework/rules/ef-standards.md +20 -0
  48. package/framework/rules/frontend-standards.md +1 -1
  49. package/framework/rules/hangfire-standards.md +1 -1
  50. package/framework/rules/implement-report.md +25 -0
  51. package/framework/rules/infrastructure-standards.md +2 -0
  52. package/framework/rules/neon-auth-standards.md +1 -1
  53. package/framework/rules/neon-standards.md +3 -3
  54. package/framework/rules/nextjs-standards.md +7 -0
  55. package/framework/rules/plan-grammar.md +53 -0
  56. package/framework/rules/ui-design.md +27 -0
  57. package/framework/schemas/config.schema.json +11 -18
  58. package/framework/schemas/feature.schema.json +7 -1
  59. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  60. package/framework/skills/core/create-umbraco-lp/references/umbraco-lp-patterns.md +1 -1
  61. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +2 -2
  62. package/framework/skills/core/morph-apply/SKILL.md +39 -166
  63. package/framework/skills/core/morph-apply/references/debugging.md +8 -0
  64. package/framework/skills/core/morph-apply/references/hotfix.md +42 -0
  65. package/framework/skills/core/morph-apply/references/machine.md +29 -0
  66. package/framework/skills/core/{morph-media/SKILL.md → morph-apply/references/media.md} +11 -74
  67. package/framework/skills/core/morph-apply/references/review.md +65 -0
  68. package/framework/skills/core/morph-plan/SKILL.md +49 -109
  69. package/framework/skills/core/morph-plan/references/critique.md +43 -0
  70. package/framework/skills/core/morph-plan/references/interview.md +37 -0
  71. package/framework/skills/core/morph-uiux/SKILL.md +47 -64
  72. package/framework/skills/core/morph-uiux/surfaces.json +32 -0
  73. package/framework/standards/STANDARDS.json +51 -28
  74. package/framework/standards/STANDARDS.meta.json +16 -19
  75. package/framework/standards/ai-agents/agent-session.md +2 -3
  76. package/framework/standards/ai-agents/context-providers.md +2 -2
  77. package/framework/standards/ai-agents/durable-workflows-hitl.md +2 -2
  78. package/framework/standards/ai-agents/providers/model-registry.md +2 -2
  79. package/framework/standards/ai-agents/rag-custom-pgvector.md +7 -6
  80. package/framework/standards/ai-agents/setup.md +1 -1
  81. package/framework/standards/ai-agents/tool-adapters.md +2 -2
  82. package/framework/standards/architecture/stack-baseline.md +70 -0
  83. package/framework/standards/backend/database/postgresql/database.md +22 -1
  84. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +33 -1
  85. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +2 -1
  86. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +12 -13
  87. package/framework/standards/frontend/design-system/ai-image-generation.md +51 -12
  88. package/framework/standards/frontend/design-system/ai-video-generation.md +50 -4
  89. package/framework/standards/frontend/design-system/art-direction.md +2 -2
  90. package/framework/standards/frontend/scroll-driven/frame-scrub.md +12 -2
  91. package/framework/standards/frontend/scroll-driven/scroll-components.md +76 -4
  92. package/framework/standards/infrastructure/docker/local-compose-isolation.md +2 -2
  93. package/framework/standards/infrastructure/neon/neon-pgvector.md +62 -20
  94. package/framework/standards/infrastructure/neon/neon-platform.md +61 -0
  95. package/framework/standards/infrastructure/neon/neon-setup.md +14 -13
  96. package/framework/standards/integration/mcp/mcp-tools.md +20 -20
  97. package/framework/templates/REGISTRY.json +1 -2
  98. package/framework/templates/context/ARCHITECTURE.md +1 -1
  99. package/framework/templates/docs/plan.md +15 -12
  100. package/framework/templates/docs/ui-mockups.md +17 -105
  101. package/framework/templates/infrastructure/docker/docker-compose.template.yml +1 -1
  102. package/package.json +1 -1
  103. package/src/commands/e2e/e2e.js +88 -23
  104. package/src/commands/graph/diff.js +74 -0
  105. package/src/commands/graph/status.js +1 -1
  106. package/src/commands/observability/cost.js +2 -4
  107. package/src/commands/observability/telemetry.js +1 -1
  108. package/src/commands/project/doctor.js +23 -39
  109. package/src/commands/project/fleet.js +5 -6
  110. package/src/commands/project/init.js +63 -36
  111. package/src/commands/project/stack-scan.js +3 -42
  112. package/src/commands/project/stack-set.js +26 -0
  113. package/src/commands/project/status.js +12 -13
  114. package/src/commands/project/update.js +39 -3
  115. package/src/commands/project/worktree.js +3 -14
  116. package/src/commands/state/advance.js +17 -17
  117. package/src/commands/state/approve.js +0 -6
  118. package/src/commands/state/archive.js +27 -1
  119. package/src/commands/state/auto-approval.js +2 -2
  120. package/src/commands/state/create.js +1 -6
  121. package/src/commands/state/gate-check.js +38 -31
  122. package/src/commands/state/gate-decision.js +3 -2
  123. package/src/commands/state/next.js +1 -0
  124. package/src/commands/state/recap.js +67 -0
  125. package/src/commands/state/report-check.js +36 -178
  126. package/src/commands/validation/plan-check.js +16 -11
  127. package/src/commands/validation/validate-feature.js +3 -3
  128. package/src/commands/validation/verify.js +3 -6
  129. package/src/core/paths/output-schema.js +3 -3
  130. package/src/core/state/state-manager.js +2 -4
  131. package/src/dashboard/app/components/CommandPalette.jsx +2 -5
  132. package/src/dashboard/app/components/GatePauses.jsx +116 -0
  133. package/src/dashboard/app/components/SessionMap.jsx +77 -0
  134. package/src/dashboard/app/pages/Activity.jsx +4 -0
  135. package/src/dashboard/app/pages/AgentMap.jsx +1 -2
  136. package/src/dashboard/app/pages/FeatureDetail.jsx +129 -186
  137. package/src/dashboard/app/pages/Features.jsx +7 -7
  138. package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
  139. package/src/dashboard/app/pages/Portfolio.jsx +40 -5
  140. package/src/dashboard/scanner/activity-scanner.js +29 -0
  141. package/src/dashboard/scanner/agents-scanner.js +11 -14
  142. package/src/dashboard/scanner/features-scanner.js +45 -24
  143. package/src/dashboard/scanner/project-api.js +11 -2
  144. package/src/dashboard/scanner/skills-scanner.js +11 -1
  145. package/src/lib/detectors/index.js +1 -1
  146. package/src/lib/e2e/applicability.js +3 -1
  147. package/src/lib/git/tree-state.js +1 -16
  148. package/src/lib/graph/diff-tree.js +127 -0
  149. package/src/lib/graph/graphify-runtime.js +12 -5
  150. package/src/lib/installers/memory-installer.js +3 -3
  151. package/src/lib/installers/rules-installer.js +57 -0
  152. package/src/lib/installers/stack-assets.js +17 -0
  153. package/src/lib/installers/stack-sync.js +219 -0
  154. package/src/lib/plan/checks.js +61 -109
  155. package/src/lib/plan/critique.js +28 -0
  156. package/src/lib/plan/media.js +42 -0
  157. package/src/lib/plan/plan-html.js +125 -0
  158. package/src/lib/plan/plan-parser.js +34 -45
  159. package/src/lib/recap/piper.js +36 -0
  160. package/src/lib/recap/recap.js +232 -0
  161. package/src/lib/review-reports.js +28 -4
  162. package/src/lib/risk-detector.js +90 -11
  163. package/src/lib/specs/screen-checklist.js +33 -48
  164. package/src/lib/stack/dotnet-build-ignores.js +8 -9
  165. package/src/lib/telemetry/metrics.js +27 -29
  166. package/src/lib/validators/reuse/reuse-validator.js +1 -9
  167. package/src/lib/validators/verify-runner.js +0 -7
  168. package/src/lib/worktree/fleet-scanner.js +7 -20
  169. package/src/lib/worktree/worktree-audit.js +0 -37
  170. package/src/scripts/setup-infra.js +15 -50
  171. package/src/utils/agents-installer.js +27 -201
  172. package/src/utils/hooks-installer.js +11 -95
  173. package/framework/hooks/claude-code/core/warn-bash-source-write.js +0 -23
  174. package/framework/hooks/claude-code/statusline.py +0 -699
  175. package/framework/hooks/claude-code/statusline.sh +0 -11
  176. package/framework/hooks/shared/agent-reap.js +0 -74
  177. package/framework/hooks/shared/slice-progress.js +0 -110
  178. package/framework/skills/core/morph-hotfix/SKILL.md +0 -133
  179. package/framework/skills/core/morph-machine/SKILL.md +0 -46
  180. package/framework/skills/core/morph-review/SKILL.md +0 -129
  181. package/framework/skills/core/morph-standards/SKILL.md +0 -52
  182. package/framework/standards/PROVENANCE.json +0 -119
  183. package/framework/standards/infrastructure/neon/neon-pgrag.md +0 -243
  184. package/src/commands/project/worktree-reap.js +0 -34
  185. package/src/commands/state/handoff.js +0 -65
  186. package/src/commands/validation/mutate.js +0 -263
  187. package/src/commands/validation/scout-check.js +0 -28
  188. package/src/lib/generators/handoff-generator.js +0 -172
  189. package/src/lib/mutation/adapters.js +0 -79
  190. package/src/lib/mutation/commands.js +0 -61
  191. package/src/lib/mutation/dotnet-introspection.js +0 -281
  192. package/src/lib/mutation/manifest.js +0 -144
  193. package/src/lib/mutation/plan.js +0 -44
  194. package/src/lib/mutation/report.js +0 -68
  195. package/src/lib/mutation/runner.js +0 -301
  196. package/src/lib/mutation/schemata.js +0 -60
  197. package/src/lib/mutation/snapshot.js +0 -65
  198. package/src/lib/mutation/subset.js +0 -109
  199. package/src/lib/mutation/trx.js +0 -50
  200. package/src/lib/scout/scout-check.js +0 -293
  201. package/src/lib/validators/traceability-check.js +0 -103
  202. package/src/lib/worktree/agent-reaper.js +0 -247
@@ -1,119 +0,0 @@
1
- {
2
- "version": "1.0.0",
3
- "_note": "Standards distilled from an external source. The source is not a dependency at runtime: it lives in another repository and is not needed to use the framework. The same mechanism covers content distilled into a SKILL — an entry declares `standards`, `skills`, or both, and every declared name must resolve. This file exists so drift is detectable instead of silent. Pin `sourceTree` when distilling, and re-pin deliberately after reviewing what changed. See test/framework/standards-provenance.test.js.",
4
- "sources": [
5
- {
6
- "id": "morph-lp-cinematic",
7
- "repo": "morph-HUB",
8
- "path": "skills/morph-lp-cinematic",
9
- "envVar": "MORPH_HUB",
10
- "defaultCheckout": "R:/Polymorphism Tech/repos/morph-HUB",
11
- "sourceTree": "2987b44241cae479b1aedc63f689cdcd6ef6fb94",
12
- "sourceCommit": "c4c9164",
13
- "distilledOn": "2026-08-21",
14
- "distilledFrom": [
15
- "references/build-stack.md",
16
- "references/component-recipes.md",
17
- "references/premium-finish.md",
18
- "references/seo-and-qa.md",
19
- "references/image-prompt.md",
20
- "references/seedance-scrub-prompt.md",
21
- "references/seedance-loop-prompt.md"
22
- ],
23
- "notDistilled": [
24
- "references/last-mile.md",
25
- "references/copy-and-messaging.md",
26
- "references/section-blueprint.md"
27
- ],
28
- "notDistilledReason": "Deliberate split: a standard carries knowledge, a skill carries process. Deploy and copy strategy stay with the skill. `references/gates.md` LEFT this list on 2026-09-09: the reason that kept it out was \"a skill carries process\", and the destination is now a skill — see the \"cinematic-lp\" source below, which distils it into morph-media. Review of 2026-09-29 (source c4c9164): only tool-independent facts were ported (the scrub_frames manifest contract for frame-scrub, chained clips for ai-video-generation); the rest was already in the standards or stays with the skill (ffmpeg-to-media_tool swaps, model prices, SKILL.md, gates.md, assets/).",
29
- "standards": [
30
- "frontend-scroll-driven-frame-scrub",
31
- "frontend-scroll-driven-smooth-scroll",
32
- "frontend-scroll-driven-scroll-components",
33
- "frontend-design-system-premium-finish",
34
- "frontend-design-system-ai-image-generation",
35
- "frontend-design-system-ai-video-generation",
36
- "frontend-seo-meta-schema-audit"
37
- ],
38
- "skills": []
39
- },
40
- {
41
- "id": "morph-image",
42
- "repo": "morph-HUB",
43
- "path": "skills/morph-image",
44
- "envVar": "MORPH_HUB",
45
- "defaultCheckout": "R:/Polymorphism Tech/repos/morph-HUB",
46
- "sourceTree": "e55dcf307278583120601c3c5d55118302335f7b",
47
- "sourceCommit": "c4c9164",
48
- "distilledOn": "2026-09-09",
49
- "distilledFrom": [
50
- "SKILL.md"
51
- ],
52
- "notDistilled": [
53
- "skill.json",
54
- "evals/"
55
- ],
56
- "notDistilledReason": "Manifest and eval fixtures of the source skill: packaging of the origin, not knowledge. The MCP tool names of the source were also NOT carried over — morph-media is about the authoring decisions, and a tool table pinned to one MCP server would rot on its own.",
57
- "standards": [],
58
- "skills": [
59
- "morph-media"
60
- ]
61
- },
62
- {
63
- "id": "cinematic-lp",
64
- "repo": "morph-HUB",
65
- "path": "skills/cinematic-lp/references",
66
- "envVar": "MORPH_HUB",
67
- "defaultCheckout": "R:/Polymorphism Tech/repos/morph-HUB",
68
- "sourceTree": "3c557425d649ed477bf6645b9297b6d1d72ae4a3",
69
- "sourceCommit": "c4c9164",
70
- "distilledOn": "2026-09-09",
71
- "distilledFrom": [
72
- "gates.md"
73
- ],
74
- "notDistilled": [
75
- "build-stack.md",
76
- "component-recipes.md",
77
- "copy-and-messaging.md",
78
- "image-prompt.md",
79
- "last-mile.md",
80
- "mcp-setup.md",
81
- "premium-finish.md",
82
- "section-blueprint.md",
83
- "seo-and-qa.md",
84
- "video-loop-examples.md",
85
- "video-loop-prompt.md",
86
- "video-scrub-prompt.md"
87
- ],
88
- "notDistilledReason": "Only the HITL gate mechanics were distilled: the N-option picker, \"rejection goes back to the same step\", and \"show MOVEMENT, never a still\". The rest is either already a standard (the frame-scrub / smooth-scroll / premium-finish family, from the morph-lp-cinematic source above) or build/deploy strategy that belongs to the calling workflow. Review of 2026-09-29 (source c4c9164): gates.md did not change; the changes were in image-prompt.md and mcp-setup.md, both not distilled. Re-pinned only.",
89
- "standards": [],
90
- "skills": [
91
- "morph-media"
92
- ]
93
- },
94
- {
95
- "id": "brand-design",
96
- "repo": "morph-HUB",
97
- "path": "skills/brand-design/references",
98
- "envVar": "MORPH_HUB",
99
- "defaultCheckout": "R:/Polymorphism Tech/repos/morph-HUB",
100
- "sourceTree": "7b637a08e931d8b7ba5be7fc75b851d89cd6e6f4",
101
- "sourceCommit": "c4c9164",
102
- "distilledOn": "2026-09-09",
103
- "distilledFrom": [
104
- "image-generation.md"
105
- ],
106
- "notDistilled": [
107
- "brand-book.md",
108
- "checklist.md",
109
- "example-identidade-visual.md",
110
- "phases.md"
111
- ],
112
- "notDistilledReason": "Only the image-per-phase map and the \"concept, never the final vector\" rule were distilled. The narrative prompt recipes were NOT copied verbatim: they are bound to one brand pipeline, and morph-media carries the prompt STRUCTURE instead, which survives the model changing. Brand book, checklist and phases are the process of another skill. Review of 2026-09-29 (source c4c9164): the image-per-phase table and the \"concept, never the final vector\" rule are unchanged (the text now says \"image model\" instead of Gemini); what was added is morph-assets call mechanics (project_set, @brand, outputPath, models, variants, dryRun), tool-bound and kept out on purpose. Re-pinned only.",
113
- "standards": [],
114
- "skills": [
115
- "morph-media"
116
- ]
117
- }
118
- ]
119
- }
@@ -1,243 +0,0 @@
1
- # Neon pgrag Standard
2
-
3
- > **Scope:** neon
4
- > **Layer:** 2 (on keyword)
5
- > **Keywords:** pgrag, rag, chunking, embedding, reranking, retrieval
6
- > **Load When:** pgrag or in-database RAG keywords detected
7
-
8
- **Verified against:** Neon pgrag (`rag` extension family — experimental, see Core Rules). Last-verified: 2026-05-20.
9
-
10
- ---
11
-
12
- Stack: Neon Serverless Postgres
13
-
14
- ## Core Rules
15
-
16
- - pgrag is EXPERIMENTAL -- API may change between Neon releases
17
- - ALWAYS enable unstable extensions before installing: `SET neon.allow_unstable_extensions='true'`
18
- - Use pgrag for simple, self-contained RAG pipelines (PDF ingestion, chunking, search)
19
- - Use application-level custom RAG (a typed MAF tool over pgvector — see standard ai-agents-rag-custom-pgvector) for complex workflows requiring custom logic, multi-model orchestration, or .NET integration
20
- - NEVER use pgrag local embeddings (384 dims) when your application uses a different embedding model -- dimension mismatch breaks search
21
-
22
- ## Install pgrag
23
-
24
- ```sql
25
- -- Enable unstable extensions (required)
26
- SET neon.allow_unstable_extensions='true';
27
-
28
- -- Core extension
29
- CREATE EXTENSION IF NOT EXISTS rag CASCADE;
30
-
31
- -- Local embedding model (bge-small-en-v1.5, 384 dimensions, 33M params)
32
- CREATE EXTENSION IF NOT EXISTS rag_bge_small_en_v15 CASCADE;
33
-
34
- -- Local reranker (jina-reranker-v1-tiny-en, 33M params)
35
- CREATE EXTENSION IF NOT EXISTS rag_jina_reranker_v1_tiny_en CASCADE;
36
- ```
37
-
38
- ## Text Extraction
39
-
40
- Extract text from binary documents directly in SQL:
41
-
42
- ```sql
43
- -- Extract text from PDF
44
- SELECT rag.text_from_pdf(pg_read_binary_file('/path/to/document.pdf'));
45
-
46
- -- Extract text from DOCX
47
- SELECT rag.text_from_docx(pg_read_binary_file('/path/to/document.docx'));
48
-
49
- -- Convert HTML to Markdown
50
- SELECT rag.markdown_from_html('<h1>Title</h1><p>Content here</p>');
51
- ```
52
-
53
- ### From a Documents Table
54
-
55
- ```sql
56
- CREATE TABLE raw_documents (
57
- id SERIAL PRIMARY KEY,
58
- filename TEXT NOT NULL,
59
- content BYTEA NOT NULL,
60
- extracted_text TEXT
61
- );
62
-
63
- -- Extract text on insert
64
- UPDATE raw_documents
65
- SET extracted_text = rag.text_from_pdf(content)
66
- WHERE filename LIKE '%.pdf' AND extracted_text IS NULL;
67
- ```
68
-
69
- ## Chunking Strategies
70
-
71
- ### Character-Based Chunking
72
-
73
- Splits text by character count with overlap for context continuity:
74
-
75
- ```sql
76
- -- Split into chunks of 1000 chars with 200 char overlap
77
- SELECT unnest(
78
- rag.chunks_by_character_count(
79
- 'Your long document text here...',
80
- 1000, -- max_chars per chunk
81
- 200 -- overlap chars
82
- )
83
- );
84
- ```
85
-
86
- ### Token-Based Chunking
87
-
88
- Uses the bge-small-en-v1.5 tokenizer for model-aware splitting:
89
-
90
- ```sql
91
- -- Split into chunks of 512 tokens with 50 token overlap
92
- SELECT unnest(
93
- rag_bge_small_en_v15.chunks_by_token_count(
94
- 'Your long document text here...',
95
- 512, -- max_tokens per chunk
96
- 50 -- overlap tokens
97
- )
98
- );
99
- ```
100
-
101
- ## Embedding Generation
102
-
103
- ### Local Embeddings (bge-small-en-v1.5)
104
-
105
- Zero-cost, runs on the database server. Produces 384-dimension vectors:
106
-
107
- ```sql
108
- -- Embedding for a document passage (includes "passage:" prefix internally)
109
- SELECT rag_bge_small_en_v15.embedding_for_passage('Neon is a serverless Postgres platform');
110
-
111
- -- Embedding for a search query (includes "query:" prefix internally)
112
- SELECT rag_bge_small_en_v15.embedding_for_query('What is Neon?');
113
- ```
114
-
115
- ### OpenAI Embeddings (text-embedding-3-small)
116
-
117
- Remote API call, produces 1536-dimension vectors:
118
-
119
- ```sql
120
- -- Set API key (per session)
121
- SET neon.ai_api_key = 'sk-...';
122
-
123
- -- Generate embedding via OpenAI
124
- SELECT rag.openai_text_embedding_3_small('Neon is a serverless Postgres platform');
125
- ```
126
-
127
- ## Full RAG Pipeline Example
128
-
129
- ```sql
130
- -- 1. Create chunks table
131
- CREATE TABLE chunks (
132
- id SERIAL PRIMARY KEY,
133
- document_id INT REFERENCES raw_documents(id),
134
- chunk_text TEXT NOT NULL,
135
- embedding vector(384)
136
- );
137
-
138
- -- 2. Chunk and embed a document
139
- WITH doc AS (
140
- SELECT id, rag.text_from_pdf(content) AS full_text
141
- FROM raw_documents WHERE id = 1
142
- ),
143
- chunked AS (
144
- SELECT doc.id AS document_id, unnest(
145
- rag.chunks_by_character_count(doc.full_text, 1000, 200)
146
- ) AS chunk_text
147
- FROM doc
148
- )
149
- INSERT INTO chunks (document_id, chunk_text, embedding)
150
- SELECT document_id, chunk_text,
151
- rag_bge_small_en_v15.embedding_for_passage(chunk_text)
152
- FROM chunked;
153
-
154
- -- 3. Create HNSW index
155
- CREATE INDEX idx_chunks_embedding ON chunks
156
- USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
157
- ```
158
-
159
- ## Similarity Search
160
-
161
- ```sql
162
- -- Find top 10 similar chunks
163
- SELECT id, chunk_text,
164
- 1 - (embedding <=> rag_bge_small_en_v15.embedding_for_query('What is Neon?')) AS similarity
165
- FROM chunks
166
- ORDER BY embedding <=> rag_bge_small_en_v15.embedding_for_query('What is Neon?')
167
- LIMIT 10;
168
- ```
169
-
170
- ## Reranking
171
-
172
- Reranking refines initial vector search results using a cross-encoder model for higher accuracy:
173
-
174
- ```sql
175
- -- Rerank top 10 vector results down to top 5
176
- WITH vector_matches AS (
177
- SELECT id, chunk_text,
178
- 1 - (embedding <=> rag_bge_small_en_v15.embedding_for_query('What is Neon?')) AS similarity
179
- FROM chunks
180
- ORDER BY embedding <=> rag_bge_small_en_v15.embedding_for_query('What is Neon?')
181
- LIMIT 10
182
- )
183
- SELECT id, chunk_text, similarity,
184
- rag_jina_reranker_v1_tiny_en.rerank_distance('What is Neon?', chunk_text) AS rerank_score
185
- FROM vector_matches
186
- ORDER BY rerank_score ASC
187
- LIMIT 5;
188
- ```
189
-
190
- ## LLM Integration in SQL
191
-
192
- Send context + question to an LLM directly from SQL:
193
-
194
- ```sql
195
- -- Set API key
196
- SET neon.ai_api_key = 'sk-...';
197
-
198
- -- Ask a question with retrieved context
199
- WITH context AS (
200
- SELECT string_agg(chunk_text, E'\n---\n') AS combined_context
201
- FROM (
202
- SELECT chunk_text FROM chunks
203
- ORDER BY embedding <=> rag_bge_small_en_v15.embedding_for_query('What is Neon?')
204
- LIMIT 5
205
- ) top_chunks
206
- )
207
- SELECT rag.openai_chat_completion(
208
- json_build_object(
209
- 'model', 'gpt-4o',
210
- 'messages', json_build_array(
211
- json_build_object('role', 'system', 'content',
212
- 'Answer based on the provided context. If unsure, say so.'),
213
- json_build_object('role', 'user', 'content',
214
- format('Context:\n%s\n\nQuestion: What is Neon?', context.combined_context))
215
- )
216
- )
217
- ) FROM context;
218
- ```
219
-
220
- ## When to Use pgrag vs Application-Level RAG
221
-
222
- | Factor | pgrag (In-Database) | SK + pgvector (Application) |
223
- |--------|---------------------|----------------------------|
224
- | Setup complexity | Minimal -- SQL only | Requires .NET service layer |
225
- | Embedding model | Local (384d) or OpenAI | Any model via SK connectors |
226
- | Reranking | Built-in (Jina) | Custom implementation |
227
- | Custom logic | Limited to SQL | Full C# flexibility |
228
- | Multi-model orchestration | Not supported | Native SK capability |
229
- | Production readiness | Experimental | Stable (SK GA) |
230
- | Cost | Zero for local models | API costs for remote models |
231
- | Best for | Prototyping, simple RAG, SQL-only environments | Production .NET applications, complex pipelines |
232
-
233
- **Recommendation:** Start with pgrag for prototyping and validation. Migrate to custom RAG (a typed MAF vector-search tool over pgvector — see ai-agents-rag-custom-pgvector) for production .NET applications that need custom retrieval logic, multi-model orchestration, or MAF agent integration.
234
-
235
- ## Common Mistakes
236
-
237
- | Wrong | Right | Why |
238
- |-------|-------|-----|
239
- | Missing `neon.allow_unstable_extensions` | `SET neon.allow_unstable_extensions='true'` | pgrag won't install without it |
240
- | Mixing local (384d) and OpenAI (1536d) embeddings | Use one model consistently per column | Dimension mismatch breaks similarity search |
241
- | No HNSW index on chunks table | Create index after initial data load | Full table scan on every search |
242
- | Using pgrag in production without testing | Validate with representative data first | Extension is experimental, may change |
243
- | Storing API key in SQL scripts | Use session variables or environment config | Keys in scripts leak to version control |
@@ -1,34 +0,0 @@
1
- import chalk from 'chalk';
2
- import { reapAgentWorktrees } from '../../lib/worktree/agent-reaper.js';
3
-
4
- const label = (item) => item.path ?? item.branch ?? item.hex;
5
-
6
- function printReport(out) {
7
- const mode = out.dryRun ? ' (simulação)' : '';
8
- console.log(chalk.bold(`\nWorktrees de sub-agent${mode} — graça de ${out.graceMinutes} min\n`));
9
- if (out.busy) console.log(chalk.yellow(' ⏳ outro reaper está em execução; nada foi feito\n'));
10
-
11
- for (const item of out.wouldReap ?? []) console.log(chalk.cyan(` → removeria: ${label(item)}`));
12
- for (const item of out.reaped) console.log(chalk.green(` ✓ removido: ${label(item)}${item.backup ? chalk.gray(` (backup: ${item.backup})`) : ''}`));
13
- for (const item of out.preserved) {
14
- console.log(chalk.yellow(` ⚠ preservado: ${label(item)} — ${item.reason}${item.detail ? `: ${item.detail}` : ''}`));
15
- }
16
- if (out.active) console.log(chalk.gray(` ${out.active} agente(s) ainda ativo(s), intocado(s)`));
17
- const nothing = !out.reaped.length && !out.preserved.length && !out.active && !(out.wouldReap ?? []).length;
18
- if (nothing && !out.busy) console.log(chalk.green(' ✓ nenhuma worktree de sub-agent sobrando'));
19
- console.log();
20
- }
21
-
22
- export async function worktreeReapCommand(options = {}) {
23
- const grace = options.grace === undefined ? undefined : Number(options.grace);
24
- if (grace !== undefined && !(Number.isFinite(grace) && grace >= 0)) {
25
- console.error(chalk.red(`--grace precisa ser um número de minutos >= 0 (recebi "${options.grace}")`));
26
- process.exit(2);
27
- }
28
-
29
- const out = await reapAgentWorktrees(options.cwd || process.cwd(), { dryRun: options.dryRun === true, graceMinutes: grace });
30
- if (options.json) console.log(JSON.stringify(out));
31
- else if (out.ok) printReport(out);
32
- else console.log(chalk.gray(` fora de um repositório git — nada a fazer (${out.error})`));
33
- return out;
34
- }
@@ -1,65 +0,0 @@
1
- import chalk from 'chalk';
2
- import { buildHandoff, writeHandoff } from '../../lib/generators/handoff-generator.js';
3
- import { resolveFeatureTree } from '../../lib/worktree/feature-truth.js';
4
-
5
- // With a live worktree the root copy is a stale birth skeleton: build and write in the
6
- // owning tree (`resolveFeatureTree`) unless `--here` forces the cwd.
7
- export function handoffCommand(featureName, options = {}) {
8
- const cwd = process.cwd();
9
-
10
- const owner = options.here ? { source: 'cwd', tree: cwd, branch: null, worktree: null } : resolveFeatureTree(featureName, cwd);
11
-
12
- if (owner.source === 'none') {
13
- if (options.json) {
14
- console.log(JSON.stringify({ error: 'feature-not-found', feature: featureName }));
15
- } else {
16
- console.error(chalk.red(`\n❌ Feature not found: ${featureName}\n`));
17
- }
18
- process.exit(1);
19
- }
20
-
21
- if (owner.source === 'branch-only') {
22
- // The handoff points at files on disk; a truth materialized in no tree is refused.
23
- const hint = `morph-spec worktree setup ${featureName} (ou: git checkout ${owner.branch})`;
24
- if (options.json) {
25
- console.log(JSON.stringify({ error: 'feature-not-in-tree', feature: featureName, branch: owner.branch, hint }));
26
- } else {
27
- console.error(chalk.red(`\n❌ "${featureName}" está commitada em \`${owner.branch}\`, mas não está materializada em árvore nenhuma.`));
28
- console.error(chalk.gray(` ${hint}\n`));
29
- }
30
- process.exit(1);
31
- }
32
-
33
- const tree = owner.tree;
34
- const result = buildHandoff(featureName, tree, { worktree: owner.worktree });
35
- if (!result) {
36
- if (options.json) {
37
- console.log(JSON.stringify({ error: 'feature-not-found', feature: featureName, tree }));
38
- } else {
39
- console.error(chalk.red(`\n❌ Feature not found: ${featureName}\n`));
40
- }
41
- process.exit(1);
42
- }
43
-
44
- const path = writeHandoff(featureName, tree, { worktree: owner.worktree });
45
- if (!path) {
46
- if (options.json) {
47
- console.log(JSON.stringify({ error: 'write-failed', feature: featureName, tree }));
48
- } else {
49
- console.error(chalk.red(`\n❌ Could not write handoff.md for ${featureName}\n`));
50
- }
51
- process.exit(1);
52
- }
53
-
54
- if (options.json) {
55
- console.log(JSON.stringify({ path, feature: featureName, tree, source: owner.source, ...result.meta }));
56
- return;
57
- }
58
-
59
- console.log(chalk.green(`\n✅ Handoff gerado: ${path}`));
60
- if (tree !== cwd) {
61
- console.log(chalk.yellow(` resolvido para ${tree} — a cópia da raiz é esqueleto de nascimento, não a verdade.`));
62
- }
63
- console.log(chalk.gray(` fase ${result.meta.phase} · fatias ${result.meta.slicesDone}/${result.meta.slicesTotal} · ${result.meta.generatedAt}`));
64
- console.log(chalk.gray(' A próxima sessão lê este documento antes de continuar (ponteiros, não cópias).\n'));
65
- }