@polymorphism-tech/morph-spec 6.0.0 → 7.1.0
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.
- package/README.md +367 -366
- package/docs/CHEATSHEET.md +3 -3
- package/docs/QUICKSTART.md +4 -4
- package/framework/CLAUDE.md +13 -0
- package/framework/MORPH.md +57 -36
- package/framework/agents.json +132 -127
- package/framework/commands/morph-apply.md +4 -21
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-proposal.md +2 -0
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +1 -1
- package/framework/hooks/claude-code/core/state-sync.js +212 -0
- package/framework/hooks/shared/phase-utils.js +5 -4
- package/framework/hooks/shared/state-reader.js +1 -1
- package/framework/phases.json +1 -1
- package/framework/rubrics/backend.json +41 -36
- package/framework/rules/ai-agents-standards.md +45 -15
- package/framework/rules/morph-workflow.md +15 -34
- package/framework/rules/neon-standards.md +25 -26
- package/framework/schemas/tasks.schema.json +35 -0
- package/framework/skills/core/morph-apply/SKILL.md +154 -0
- package/framework/skills/core/morph-brainstorming/SKILL.md +53 -30
- package/framework/skills/core/morph-implement/SKILL.md +25 -14
- package/framework/skills/core/morph-plan/SKILL.md +91 -23
- package/framework/skills/core/morph-proposal/SKILL.md +137 -0
- package/framework/skills/core/morph-review/SKILL.md +43 -7
- package/framework/skills/core/morph-stack-scan/SKILL.md +40 -1
- package/framework/standards/STANDARDS.json +1729 -1134
- package/framework/standards/ai-agents/agent-session.md +160 -0
- package/framework/standards/ai-agents/batching.md +193 -0
- package/framework/standards/ai-agents/context-providers.md +188 -0
- package/framework/standards/ai-agents/mcp-server.md +250 -0
- package/framework/standards/ai-agents/mcp-tools.md +197 -0
- package/framework/standards/ai-agents/middleware-patterns.md +207 -0
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -0
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -0
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -0
- package/framework/standards/ai-agents/modalities-vision.md +201 -0
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -0
- package/framework/standards/ai-agents/production.md +114 -258
- package/framework/standards/ai-agents/prompts-in-db.md +214 -0
- package/framework/standards/ai-agents/providers/model-registry.md +158 -0
- package/framework/standards/ai-agents/rag-custom-pgvector.md +243 -0
- package/framework/standards/ai-agents/service-tier-flex.md +135 -0
- package/framework/standards/ai-agents/setup.md +142 -316
- package/framework/standards/ai-agents/structured-output.md +249 -0
- package/framework/standards/ai-agents/sweet-spot.md +109 -0
- package/framework/standards/ai-agents/workflows.md +114 -284
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +433 -429
- package/framework/standards/backend/api/validation.md +92 -88
- package/framework/standards/backend/database/postgresql/database.md +336 -332
- package/framework/standards/backend/database/vector-search-rag.md +599 -541
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +4 -0
- package/framework/standards/backend/dotnet/result-pattern.md +4 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +176 -172
- package/framework/standards/backend/dotnet/scrutor.md +4 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +278 -274
- package/framework/standards/backend/integrations/asaas/asaas-api.md +260 -216
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +354 -350
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +30 -19
- package/framework/standards/backend/integrations/resend/resend-email.md +400 -385
- package/framework/standards/data/nosql/cache/redis.md +106 -97
- package/framework/standards/data/nosql/cosmos-db.md +127 -118
- package/framework/standards/data/vector-search/rag-chunking.md +113 -104
- package/framework/standards/frontend/design-system/ai-image-generation.md +4 -0
- package/framework/standards/frontend/design-system/animations.md +164 -160
- package/framework/standards/frontend/design-system/naming.md +68 -64
- package/framework/standards/frontend/gsap/gsap-core.md +14 -8
- package/framework/standards/frontend/gsap/gsap-plugins.md +26 -21
- package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +9 -7
- package/framework/standards/frontend/nextjs/app-router.md +127 -123
- package/framework/standards/frontend/nextjs/components.md +136 -132
- package/framework/standards/frontend/nextjs/data-fetching.md +130 -126
- package/framework/standards/frontend/nextjs/forms.md +134 -128
- package/framework/standards/frontend/nextjs/motion-patterns.md +328 -322
- package/framework/standards/frontend/nextjs/naming-conventions.md +71 -67
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +229 -225
- package/framework/standards/frontend/nextjs/project-structure.md +106 -102
- package/framework/standards/frontend/nextjs/state-management.md +76 -72
- package/framework/standards/frontend/nextjs/testing.md +115 -111
- package/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -192
- package/framework/standards/infrastructure/neon/neon-pgrag.md +6 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +4 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +5 -1
- package/framework/standards/integration/mcp/mcp-tools.md +471 -462
- package/framework/templates/REGISTRY.json +1745 -1239
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -0
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -0
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -0
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -0
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -0
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -0
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -0
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -0
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -0
- package/framework/templates/docs/onboarding.md +4 -4
- package/framework/templates/tasks.template.json +17 -0
- package/package.json +89 -83
- package/src/commands/project/init.js +16 -0
- package/src/commands/validation/validate-feature.js +1 -1
- package/src/core/paths/output-schema.js +6 -6
- package/src/core/state/state-manager.js +1 -1
- package/src/core/templates/template-registry.js +289 -256
- package/src/lib/detectors/design-system-detector.js +1 -1
- package/src/lib/generators/context-generator.js +516 -518
- package/src/lib/generators/scaffold-generator.js +23 -26
- package/src/lib/installers/memory-installer.js +138 -0
- package/src/lib/phase-chain/phase-validator.js +4 -4
- package/src/lib/risk-detector.js +80 -0
- package/src/lib/tasks/tasks-json-parser.js +185 -0
- package/src/scripts/setup-infra.js +25 -0
- package/src/utils/hooks-installer.js +59 -10
- package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +0 -310
- package/framework/templates/integrations/semantic-kernel-neon.cs +0 -125
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* state-sync.js — PostToolUse hook
|
|
4
|
+
*
|
|
5
|
+
* Keeps .morph/state.json in sync with the agent's actions, without requiring
|
|
6
|
+
* the agent to think about state. Fail-open: any error returns {} silently.
|
|
7
|
+
*
|
|
8
|
+
* Triggers:
|
|
9
|
+
* - Write/Edit of .morph/features/{feature}/0-proposal/proposal.md → register feature
|
|
10
|
+
* - Write/Edit of .morph/features/{feature}/{phase}/{output} → mark output created
|
|
11
|
+
* - AskUserQuestion answered with option starting "aprovado" → advance gate
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, existsSync, renameSync, writeFileSync } from 'fs';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { loadState, stateExists } from '../../shared/state-reader.js';
|
|
17
|
+
|
|
18
|
+
const STATE_FILE = '.morph/state.json';
|
|
19
|
+
|
|
20
|
+
const PHASE_FOLDERS = {
|
|
21
|
+
'0-proposal': 'proposal',
|
|
22
|
+
'1-design': 'design',
|
|
23
|
+
'1-ui': 'uiux', // legacy alias — still recognized during folder transition
|
|
24
|
+
'2-plan': 'plan',
|
|
25
|
+
'3-implement': 'implement',
|
|
26
|
+
'4-review': 'review',
|
|
27
|
+
'5-implement': 'implement', // legacy alias
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function exit(output = {}) {
|
|
31
|
+
process.stdout.write(JSON.stringify(output));
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readStdin() {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(readFileSync(0, 'utf8') || '{}');
|
|
38
|
+
} catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function projectDir() {
|
|
44
|
+
return process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function extractFeatureName(filePath) {
|
|
48
|
+
if (!filePath) return null;
|
|
49
|
+
const normalized = String(filePath).replace(/\\/g, '/');
|
|
50
|
+
const match = normalized.match(/\.morph\/features\/([^/]+)\//);
|
|
51
|
+
return match ? match[1] : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function extractPhaseFolder(filePath) {
|
|
55
|
+
if (!filePath) return null;
|
|
56
|
+
const normalized = String(filePath).replace(/\\/g, '/');
|
|
57
|
+
const match = normalized.match(/\.morph\/features\/[^/]+\/([^/]+)\//);
|
|
58
|
+
if (!match) return null;
|
|
59
|
+
return PHASE_FOLDERS[match[1]] ?? null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function extractFilename(filePath) {
|
|
63
|
+
const normalized = String(filePath).replace(/\\/g, '/');
|
|
64
|
+
return normalized.split('/').pop();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Atomic write — temp file then rename. Mirrors state-manager.js semantics.
|
|
69
|
+
*/
|
|
70
|
+
function writeStateAtomic(cwd, state) {
|
|
71
|
+
const path = join(cwd, STATE_FILE);
|
|
72
|
+
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
73
|
+
writeFileSync(tmpPath, JSON.stringify(state, null, 2), 'utf8');
|
|
74
|
+
renameSync(tmpPath, path);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function registerFeatureIfMissing(state, featureName) {
|
|
78
|
+
if (!state.features) state.features = {};
|
|
79
|
+
if (state.features[featureName]) return false;
|
|
80
|
+
|
|
81
|
+
const now = new Date().toISOString();
|
|
82
|
+
state.features[featureName] = {
|
|
83
|
+
status: 'in_progress',
|
|
84
|
+
createdAt: now,
|
|
85
|
+
updatedAt: now,
|
|
86
|
+
approvalGates: { proposal: false, plan: false, review: false },
|
|
87
|
+
outputs: {},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (!state.metadata) state.metadata = {};
|
|
91
|
+
state.metadata.totalFeatures = Object.keys(state.features).length;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function trackOutput(state, featureName, filePath) {
|
|
96
|
+
const filename = extractFilename(filePath);
|
|
97
|
+
const feature = state.features[featureName];
|
|
98
|
+
if (!feature) return false;
|
|
99
|
+
feature.outputs ??= {};
|
|
100
|
+
const normalizedPath = String(filePath).replace(/\\/g, '/');
|
|
101
|
+
const wasMissing = !feature.outputs[filename]?.created;
|
|
102
|
+
feature.outputs[filename] = {
|
|
103
|
+
created: true,
|
|
104
|
+
path: normalizedPath,
|
|
105
|
+
};
|
|
106
|
+
feature.updatedAt = new Date().toISOString();
|
|
107
|
+
return wasMissing;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function findActiveFeature(state) {
|
|
111
|
+
if (!state.features) return null;
|
|
112
|
+
const entries = Object.entries(state.features);
|
|
113
|
+
const active = entries.find(([, f]) => f.status === 'in_progress');
|
|
114
|
+
if (active) return active[0];
|
|
115
|
+
return entries[0]?.[0] ?? null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isApprovalAnswer(answer) {
|
|
119
|
+
if (typeof answer !== 'string') return false;
|
|
120
|
+
const lower = answer.toLowerCase();
|
|
121
|
+
return (
|
|
122
|
+
lower.startsWith('aprovado') ||
|
|
123
|
+
lower.includes('pode avan') ||
|
|
124
|
+
lower.includes('pode implementar') ||
|
|
125
|
+
lower.includes('pode prosseguir')
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function gateFromQuestion(question) {
|
|
130
|
+
if (typeof question !== 'string') return null;
|
|
131
|
+
const lower = question.toLowerCase();
|
|
132
|
+
if (lower.includes('gate 1') || lower.includes('proposta')) return 'proposal';
|
|
133
|
+
if (lower.includes('gate 2') || lower.includes('plano') || lower.includes('plan')) return 'plan';
|
|
134
|
+
if (lower.includes('gate 3') || lower.includes('review')) return 'review';
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function handleWriteEdit(input, cwd) {
|
|
139
|
+
const filePath = input.tool_input?.file_path;
|
|
140
|
+
const featureName = extractFeatureName(filePath);
|
|
141
|
+
if (!featureName) return false;
|
|
142
|
+
|
|
143
|
+
const state = loadState(cwd);
|
|
144
|
+
if (!state) return false;
|
|
145
|
+
|
|
146
|
+
let changed = registerFeatureIfMissing(state, featureName);
|
|
147
|
+
const phase = extractPhaseFolder(filePath);
|
|
148
|
+
if (phase) {
|
|
149
|
+
const outputChanged = trackOutput(state, featureName, filePath);
|
|
150
|
+
changed = changed || outputChanged;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (changed) {
|
|
154
|
+
writeStateAtomic(cwd, state);
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function handleAskUserQuestion(input, cwd) {
|
|
160
|
+
const answers = input.tool_response?.answers ?? input.tool_response?.responses ?? {};
|
|
161
|
+
if (typeof answers !== 'object' || answers === null) return false;
|
|
162
|
+
|
|
163
|
+
const state = loadState(cwd);
|
|
164
|
+
if (!state) return false;
|
|
165
|
+
|
|
166
|
+
const featureName = findActiveFeature(state);
|
|
167
|
+
if (!featureName) return false;
|
|
168
|
+
|
|
169
|
+
let changed = false;
|
|
170
|
+
for (const [question, answer] of Object.entries(answers)) {
|
|
171
|
+
if (!isApprovalAnswer(answer)) continue;
|
|
172
|
+
const gate = gateFromQuestion(question);
|
|
173
|
+
if (!gate) continue;
|
|
174
|
+
|
|
175
|
+
state.features[featureName].approvalGates ??= {};
|
|
176
|
+
if (state.features[featureName].approvalGates[gate] !== true) {
|
|
177
|
+
state.features[featureName].approvalGates[gate] = true;
|
|
178
|
+
state.features[featureName].updatedAt = new Date().toISOString();
|
|
179
|
+
changed = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (changed) {
|
|
184
|
+
writeStateAtomic(cwd, state);
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function main() {
|
|
190
|
+
const cwd = projectDir();
|
|
191
|
+
if (!stateExists(cwd)) {
|
|
192
|
+
exit();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const input = readStdin();
|
|
197
|
+
const toolName = input.tool_name;
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
if (toolName === 'Write' || toolName === 'Edit') {
|
|
201
|
+
handleWriteEdit(input, cwd);
|
|
202
|
+
} else if (toolName === 'AskUserQuestion') {
|
|
203
|
+
handleAskUserQuestion(input, cwd);
|
|
204
|
+
}
|
|
205
|
+
} catch {
|
|
206
|
+
// fail-open
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
exit();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
main().catch(() => exit());
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/** Phase order */
|
|
11
|
-
export const PHASE_ORDER = ["proposal","uiux","plan","implement","review"];
|
|
11
|
+
export const PHASE_ORDER = ["proposal","uiux","plan","implement","review","sync"];
|
|
12
12
|
|
|
13
13
|
/** Map phase → allowed output subdirectory */
|
|
14
14
|
export const PHASE_DIRS = {
|
|
15
15
|
proposal: '0-proposal',
|
|
16
|
-
uiux: '1-
|
|
16
|
+
uiux: '1-design',
|
|
17
17
|
plan: '2-plan',
|
|
18
18
|
implement: '3-implement',
|
|
19
19
|
review: '4-review',
|
|
20
|
+
sync: '3-implement',
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
/** Map output type (camelCase) → phase that produces it */
|
|
@@ -47,7 +48,7 @@ export const FILENAME_TO_OUTPUT = {
|
|
|
47
48
|
'flows.md': 'uiFlows',
|
|
48
49
|
'spec.md': 'spec',
|
|
49
50
|
'mandate.md': 'mandate',
|
|
50
|
-
'tasks.
|
|
51
|
+
'tasks.json': 'tasks',
|
|
51
52
|
'decisions.md': 'decisions',
|
|
52
53
|
'recap.md': 'recap',
|
|
53
54
|
'review-report.md': 'reviewReport',
|
|
@@ -61,7 +62,7 @@ export const PROTECTED_SPEC_FILES = {
|
|
|
61
62
|
'flows.md': 'uiux',
|
|
62
63
|
'spec.md': 'plan',
|
|
63
64
|
'mandate.md': 'plan',
|
|
64
|
-
'tasks.
|
|
65
|
+
'tasks.json': 'plan',
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
/**
|
|
@@ -110,7 +110,7 @@ export function derivePhaseForFeature(featureName, projectPath) {
|
|
|
110
110
|
['4-review', 'review'],
|
|
111
111
|
['3-implement', 'implement'],
|
|
112
112
|
['2-plan', 'plan'],
|
|
113
|
-
['1-
|
|
113
|
+
['1-design', 'uiux'],
|
|
114
114
|
['0-proposal', 'proposal'],
|
|
115
115
|
];
|
|
116
116
|
for (const [folder, phase] of phaseMap) {
|
package/framework/phases.json
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "backend",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "Backend-focused rubric. Higher weight on architecture, security, and package health.",
|
|
5
|
-
"categories": {
|
|
6
|
-
"functionality": {
|
|
7
|
-
"weight": 0.
|
|
8
|
-
"validators": ["contract-compliance"],
|
|
9
|
-
"description": "Core feature correctness and contract compliance"
|
|
10
|
-
},
|
|
11
|
-
"code_quality": {
|
|
12
|
-
"weight": 0.
|
|
13
|
-
"validators": ["architecture"],
|
|
14
|
-
"description": "Architecture patterns, dependency direction, and code structure"
|
|
15
|
-
},
|
|
16
|
-
"design_ui": {
|
|
17
|
-
"weight": 0.05,
|
|
18
|
-
"validators": ["design-system", "css", "contrast", "nextjs-component"],
|
|
19
|
-
"description": "Design system compliance (minimal weight for backend projects)"
|
|
20
|
-
},
|
|
21
|
-
"security": {
|
|
22
|
-
"weight": 0.15,
|
|
23
|
-
"validators": [],
|
|
24
|
-
"description": "Security posture (agent-evaluated, no automated validator)"
|
|
25
|
-
},
|
|
26
|
-
"packages": {
|
|
27
|
-
"weight": 0.20,
|
|
28
|
-
"validators": ["packages"],
|
|
29
|
-
"description": "Dependency health, version compatibility, and deprecated packages"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "backend",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Backend-focused rubric. Higher weight on architecture, security, and package health.",
|
|
5
|
+
"categories": {
|
|
6
|
+
"functionality": {
|
|
7
|
+
"weight": 0.25,
|
|
8
|
+
"validators": ["contract-compliance"],
|
|
9
|
+
"description": "Core feature correctness and contract compliance"
|
|
10
|
+
},
|
|
11
|
+
"code_quality": {
|
|
12
|
+
"weight": 0.25,
|
|
13
|
+
"validators": ["architecture"],
|
|
14
|
+
"description": "Architecture patterns, dependency direction, and code structure"
|
|
15
|
+
},
|
|
16
|
+
"design_ui": {
|
|
17
|
+
"weight": 0.05,
|
|
18
|
+
"validators": ["design-system", "css", "contrast", "nextjs-component"],
|
|
19
|
+
"description": "Design system compliance (minimal weight for backend projects)"
|
|
20
|
+
},
|
|
21
|
+
"security": {
|
|
22
|
+
"weight": 0.15,
|
|
23
|
+
"validators": [],
|
|
24
|
+
"description": "Security posture (agent-evaluated, no automated validator)"
|
|
25
|
+
},
|
|
26
|
+
"packages": {
|
|
27
|
+
"weight": 0.20,
|
|
28
|
+
"validators": ["packages"],
|
|
29
|
+
"description": "Dependency health, version compatibility, and deprecated packages"
|
|
30
|
+
},
|
|
31
|
+
"maf_compliance": {
|
|
32
|
+
"weight": 0.10,
|
|
33
|
+
"validators": [],
|
|
34
|
+
"description": "MAF agent compliance (agent-evaluated, applies only when the feature touches AI agents): Microsoft.Agents.AI GA packages used; Model Registry alias referenced not hardcoded models; structured output for pipelined agents; prompts from DB not hardcoded; no Semantic Kernel; no hosted agent services."
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"thresholds": {
|
|
38
|
+
"approve": 8.0,
|
|
39
|
+
"retry": 6.0
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,15 +1,45 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/Agents/**"
|
|
4
|
-
- "**/agents/**"
|
|
5
|
-
- "**/*Agent*.cs"
|
|
6
|
-
stacks:
|
|
7
|
-
- dotnet
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Microsoft Agent Framework Standards
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@.morph/framework/standards/
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/Agents/**"
|
|
4
|
+
- "**/agents/**"
|
|
5
|
+
- "**/*Agent*.cs"
|
|
6
|
+
stacks:
|
|
7
|
+
- dotnet
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Microsoft Agent Framework Standards
|
|
11
|
+
|
|
12
|
+
> **Layer 0/1 — auto-carregados.** São os standards core: aplicam-se a praticamente todo
|
|
13
|
+
> agente MAF. Carregue-os sempre que tocar código de agentes.
|
|
14
|
+
|
|
15
|
+
@.morph/framework/standards/ai-agents/setup.md
|
|
16
|
+
@.morph/framework/standards/ai-agents/sweet-spot.md
|
|
17
|
+
@.morph/framework/standards/ai-agents/providers/model-registry.md
|
|
18
|
+
@.morph/framework/standards/ai-agents/structured-output.md
|
|
19
|
+
@.morph/framework/standards/ai-agents/multi-agent-patterns.md
|
|
20
|
+
@.morph/framework/standards/ai-agents/prompts-in-db.md
|
|
21
|
+
@.morph/framework/standards/ai-agents/rag-custom-pgvector.md
|
|
22
|
+
@.morph/framework/standards/ai-agents/middleware-patterns.md
|
|
23
|
+
@.morph/framework/standards/ai-agents/workflows.md
|
|
24
|
+
@.morph/framework/standards/ai-agents/production.md
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
> **Layer 2 — sob demanda (NÃO auto-carregados).** São standards de modalidade, otimização e
|
|
29
|
+
> MCP: relevantes apenas quando a feature usa especificamente esse recurso. Carregue via
|
|
30
|
+
> `morph-standards` quando uma keyword corresponder — manter fora do auto-load preserva o
|
|
31
|
+
> context window para o trabalho que importa.
|
|
32
|
+
|
|
33
|
+
| Standard | Carregue quando a feature envolve |
|
|
34
|
+
|----------|-----------------------------------|
|
|
35
|
+
| `ai-agents/modalities-vision.md` | imagem → texto (OCR, análise de documento, visão) |
|
|
36
|
+
| `ai-agents/modalities-image-gen.md` | texto → imagem (geração de mockups, posts, assets) |
|
|
37
|
+
| `ai-agents/modalities-speech-to-text.md` | áudio → texto (transcrição, legendagem) |
|
|
38
|
+
| `ai-agents/modalities-text-to-speech.md` | texto → áudio (síntese de voz) |
|
|
39
|
+
| `ai-agents/batching.md` | processar N prompts independentes em lote (Batch API) |
|
|
40
|
+
| `ai-agents/service-tier-flex.md` | otimização de custo em jobs assíncronos (tier flex) |
|
|
41
|
+
| `ai-agents/agent-session.md` | agentes conversacionais com histórico/reducers |
|
|
42
|
+
| `ai-agents/context-providers.md` | injeção dinâmica de contexto (`AIContextProvider`) |
|
|
43
|
+
| `ai-agents/mcp-tools.md` | agente MAF consome um MCP server externo |
|
|
44
|
+
| `ai-agents/mcp-server.md` | projeto expõe capacidades como MCP server |
|
|
45
|
+
| `integration/mcp/mcp-tools.md` | integração MCP cross-domain (fora do escopo MAF) |
|
|
@@ -13,20 +13,18 @@ stacks:
|
|
|
13
13
|
|
|
14
14
|
**NEVER skip to code without a specification.** Every feature must progress through phases:
|
|
15
15
|
|
|
16
|
-
1. **Proposal** —
|
|
17
|
-
2. **Design** —
|
|
18
|
-
3. **Plan** —
|
|
19
|
-
4. **
|
|
20
|
-
5. **
|
|
21
|
-
|
|
22
|
-
UI-heavy features also include **UI/UX** phase (`1-ui/`) between Design and Tasks.
|
|
16
|
+
1. **Proposal** — Problem statement + acceptance criteria (`0-proposal/proposal.md`)
|
|
17
|
+
2. **Design** (optional, UI-heavy) — Design system + mockups + flows (`1-design/`)
|
|
18
|
+
3. **Plan** — Technical spec + mandate + tasks (`2-plan/spec.md`, `mandate.md`, `tasks.json`)
|
|
19
|
+
4. **Implement** — Code + recap (`3-implement/recap.md`)
|
|
20
|
+
5. **Review** — Review report + Gate 3 (`4-review/review-report.md`)
|
|
23
21
|
|
|
24
22
|
---
|
|
25
23
|
|
|
26
24
|
## Phase Sequence
|
|
27
25
|
|
|
28
26
|
```
|
|
29
|
-
proposal → [
|
|
27
|
+
proposal → [design] → plan → implement → review
|
|
30
28
|
```
|
|
31
29
|
|
|
32
30
|
Use `morph-spec status {feature}` to see current phase and pending approval gates.
|
|
@@ -52,25 +50,11 @@ Use `morph-spec status {feature}` to see current phase and pending approval gate
|
|
|
52
50
|
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
53
51
|
| `.morph/config/config.json` | Project configuration (editable) |
|
|
54
52
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
Use `morph-spec state mark-output <feature> <type>` with one of these exact type names:
|
|
53
|
+
### output types
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| `schemaAnalysis` | design | `schema-analysis` |
|
|
63
|
-
| `spec` | design | — |
|
|
64
|
-
| `contracts` | design | — |
|
|
65
|
-
| `contractsVsa` | design | `contracts-vsa` |
|
|
66
|
-
| `decisions` | design | — |
|
|
67
|
-
| `plan` | plan | — |
|
|
68
|
-
| `tasks` | tasks | — |
|
|
69
|
-
| `uiDesignSystem` | uiux | `ui-design-system` |
|
|
70
|
-
| `uiMockups` | uiux | `ui-mockups` |
|
|
71
|
-
| `uiComponents` | uiux | `ui-components` |
|
|
72
|
-
| `uiFlows` | uiux | `ui-flows` |
|
|
73
|
-
| `recap` | implement | — |
|
|
55
|
+
Output types are defined in `src/core/paths/output-schema.js`. State sync is
|
|
56
|
+
handled automatically by the `state-sync.js` PostToolUse hook — the agent
|
|
57
|
+
does not need to call mark-output explicitly.
|
|
74
58
|
|
|
75
59
|
---
|
|
76
60
|
|
|
@@ -80,14 +64,11 @@ All outputs go in `.morph/features/{feature}/`:
|
|
|
80
64
|
|
|
81
65
|
| Phase | Path |
|
|
82
66
|
|-------|------|
|
|
83
|
-
| Proposal | `0-proposal/proposal.md` |
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
| Plan | `3-plan/plan.md` |
|
|
89
|
-
| Tasks | `4-tasks/tasks.md` |
|
|
90
|
-
| Recap | `5-implement/recap.md` |
|
|
67
|
+
| Proposal | `0-proposal/proposal.md`, `stack-scan.md`, `migration-plan.md` (optional) |
|
|
68
|
+
| Design (optional) | `1-design/design-system.md`, `mockups.md`, `components.md`, `flows.md` |
|
|
69
|
+
| Plan | `2-plan/spec.md`, `mandate.md`, `tasks.json`, `decisions.md` |
|
|
70
|
+
| Implement | `3-implement/recap.md` + source code |
|
|
71
|
+
| Review | `4-review/review-report.md` |
|
|
91
72
|
|
|
92
73
|
---
|
|
93
74
|
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/neon/**"
|
|
4
|
-
- "**/database/**"
|
|
5
|
-
- "**/*Migration*.sql"
|
|
6
|
-
- "**/*migration*.sql"
|
|
7
|
-
stacks:
|
|
8
|
-
- neon
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Neon PostgreSQL Standards
|
|
12
|
-
|
|
13
|
-
@.morph/framework/standards/infrastructure/neon/neon-setup.md
|
|
14
|
-
@.morph/framework/standards/infrastructure/neon/neon-pgvector.md
|
|
15
|
-
@.morph/framework/standards/infrastructure/neon/neon-pgrag.md
|
|
16
|
-
@.morph/framework/standards/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| PostgreSQL
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Read the template and adapt to your project structure.
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/neon/**"
|
|
4
|
+
- "**/database/**"
|
|
5
|
+
- "**/*Migration*.sql"
|
|
6
|
+
- "**/*migration*.sql"
|
|
7
|
+
stacks:
|
|
8
|
+
- neon
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Neon PostgreSQL Standards
|
|
12
|
+
|
|
13
|
+
@.morph/framework/standards/infrastructure/neon/neon-setup.md
|
|
14
|
+
@.morph/framework/standards/infrastructure/neon/neon-pgvector.md
|
|
15
|
+
@.morph/framework/standards/infrastructure/neon/neon-pgrag.md
|
|
16
|
+
@.morph/framework/standards/backend/integrations/neon-auth/neon-auth.md
|
|
17
|
+
|
|
18
|
+
## SQL Templates
|
|
19
|
+
|
|
20
|
+
| Template | Path | Purpose |
|
|
21
|
+
|----------|------|---------|
|
|
22
|
+
| PostgreSQL Migration | `.morph/framework/templates/code/sql/postgresql-migration.sql` | Database migration |
|
|
23
|
+
| PostgreSQL RLS Policy | `.morph/framework/templates/code/sql/postgresql-rls-policy.sql` | Row-level security |
|
|
24
|
+
|
|
25
|
+
Read the template and adapt to your project structure.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "MORPH-SPEC tasks.json",
|
|
4
|
+
"description": "Structured task list for a morph-spec feature. Replaces tasks.md.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["version", "feature", "tasks"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"version": { "type": "string", "const": "1.0" },
|
|
9
|
+
"feature": { "type": "string", "minLength": 1 },
|
|
10
|
+
"tasks": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"required": ["id", "title", "description", "dependencies", "effort", "doneCriteria", "status"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"id": { "type": "string", "pattern": "^T\\d+$" },
|
|
17
|
+
"title": { "type": "string", "minLength": 1 },
|
|
18
|
+
"description": { "type": "string", "minLength": 1 },
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"items": { "type": "string", "pattern": "^T\\d+$" }
|
|
22
|
+
},
|
|
23
|
+
"effort": { "type": "string", "enum": ["S", "M", "L", "XL"] },
|
|
24
|
+
"doneCriteria": { "type": "string", "minLength": 1 },
|
|
25
|
+
"status": { "type": "string", "enum": ["pending", "in_progress", "done", "skipped", "blocked"] },
|
|
26
|
+
"outputs": { "type": "array", "items": { "type": "string" } },
|
|
27
|
+
"notes": { "type": "string" },
|
|
28
|
+
"group": { "type": "string", "enum": ["backend", "frontend", "tests", "infra", "docs"] }
|
|
29
|
+
},
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"additionalProperties": false
|
|
35
|
+
}
|