@polymorphism-tech/morph-spec 8.0.0 → 8.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.
- package/README.md +2 -2
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +1 -1
- package/framework/MORPH.md +5 -5
- package/framework/agents.json +1 -1
- package/framework/commands/commit.md +166 -166
- package/framework/commands/morph-infra.md +215 -215
- package/framework/commands/morph-preflight.md +205 -205
- package/framework/commands/morph-troubleshoot.md +124 -124
- package/framework/hooks/README.md +0 -1
- package/framework/hooks/claude-code/statusline.py +679 -679
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/activity-logger.js +160 -160
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rubrics/backend.json +41 -41
- package/framework/rules/ai-agents-standards.md +45 -45
- package/framework/rules/dotnet-templates.md +86 -86
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/infrastructure-standards.md +27 -27
- package/framework/rules/neon-standards.md +25 -25
- package/framework/rules/nextjs-standards.md +20 -20
- package/framework/rules/nextjs-templates.md +40 -40
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +12 -21
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -4
- package/framework/skills/core/morph-implement/SKILL.md +10 -19
- package/framework/skills/core/morph-plan/SKILL.md +1 -1
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +11 -15
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +160 -160
- package/framework/standards/ai-agents/batching.md +193 -193
- package/framework/standards/ai-agents/context-providers.md +188 -188
- package/framework/standards/ai-agents/mcp-server.md +250 -250
- package/framework/standards/ai-agents/mcp-tools.md +197 -197
- package/framework/standards/ai-agents/middleware-patterns.md +207 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
- package/framework/standards/ai-agents/modalities-vision.md +201 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
- package/framework/standards/ai-agents/production.md +275 -275
- package/framework/standards/ai-agents/prompts-in-db.md +214 -214
- package/framework/standards/ai-agents/providers/model-registry.md +158 -158
- package/framework/standards/ai-agents/service-tier-flex.md +135 -135
- package/framework/standards/ai-agents/structured-output.md +249 -249
- package/framework/standards/ai-agents/sweet-spot.md +109 -109
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +1 -1
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/index.js +13 -13
- package/src/commands/mcp/mcp-setup.js +519 -519
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/worktree.js +83 -1
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/HookInspector.jsx +418 -418
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/hooks-scanner.js +41 -41
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/scanner/standards-scanner.js +26 -26
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/metrics-aggregator.js +56 -56
- package/src/lib/agents/metrics-calculator.js +125 -125
- package/src/lib/agents/output-collector.js +73 -73
- package/src/lib/detectors/claude-config-detector.js +152 -152
- package/src/lib/detectors/design-system-detector.js +231 -231
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/generators/architecture-scanner.js +639 -639
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/index.js +13 -13
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/validators/architecture/architecture-validator.js +259 -259
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/packages/package-validator.js +347 -347
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/validation-runner.js +349 -349
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/hooks-installer.js +3 -24
- package/src/utils/skills-installer.js +174 -174
- package/framework/hooks/claude-code/core/subagent-report-guard.js +0 -95
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Activity Logger — Session-scoped hook event log
|
|
3
|
-
*
|
|
4
|
-
* Writes hook activity to .morph/logs/activity.json for live consumption
|
|
5
|
-
* by `morph-spec monitor`.
|
|
6
|
-
*
|
|
7
|
-
* Design constraints:
|
|
8
|
-
* - Synchronous only (hooks run in process, no async overhead)
|
|
9
|
-
* - Fail-silent (never throws — hooks must not be blocked by logger)
|
|
10
|
-
* - ≤5ms per call (no retries, no network)
|
|
11
|
-
* - Windows-safe paths via path.join
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
15
|
-
import { join } from 'path';
|
|
16
|
-
|
|
17
|
-
const LOGS_DIR = '.morph/logs';
|
|
18
|
-
const ACTIVITY_FILE = join(LOGS_DIR, 'activity.json');
|
|
19
|
-
|
|
20
|
-
function getActivityPath(projectPath) {
|
|
21
|
-
return join(projectPath || process.cwd(), ACTIVITY_FILE);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function ensureLogsDir(projectPath) {
|
|
25
|
-
const dir = join(projectPath || process.cwd(), LOGS_DIR);
|
|
26
|
-
if (!existsSync(dir)) {
|
|
27
|
-
mkdirSync(dir, { recursive: true });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function readRaw(activityPath) {
|
|
32
|
-
try {
|
|
33
|
-
if (!existsSync(activityPath)) return null;
|
|
34
|
-
return JSON.parse(readFileSync(activityPath, 'utf-8'));
|
|
35
|
-
} catch {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Log a hook firing event to the session activity log.
|
|
42
|
-
*
|
|
43
|
-
* @param {string} name - Hook name (e.g. 'dispatch.js', 'enrich-prompt')
|
|
44
|
-
* @param {string} event - Claude Code event (e.g. 'PostToolUse', 'UserPromptSubmit')
|
|
45
|
-
* @param {string} result - Outcome summary (e.g. 'ok', 'blocked', 'checkpoint_saved')
|
|
46
|
-
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
47
|
-
*/
|
|
48
|
-
export function logHookActivity(name, event, result, projectPath) {
|
|
49
|
-
try {
|
|
50
|
-
const activityPath = getActivityPath(projectPath);
|
|
51
|
-
ensureLogsDir(projectPath);
|
|
52
|
-
|
|
53
|
-
const now = new Date();
|
|
54
|
-
const ts = now.toTimeString().slice(0, 8); // HH:MM:SS
|
|
55
|
-
|
|
56
|
-
const data = readRaw(activityPath) || { sessionId: '', feature: '', phase: '', hooks: [], skills: [] };
|
|
57
|
-
|
|
58
|
-
data.hooks = data.hooks || [];
|
|
59
|
-
data.hooks.push({ name, event, result, ts });
|
|
60
|
-
|
|
61
|
-
writeFileSync(activityPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
62
|
-
} catch {
|
|
63
|
-
// Fail-silent — never block hooks
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Read the current activity log.
|
|
70
|
-
*
|
|
71
|
-
* @param {string} [projectPath]
|
|
72
|
-
* @returns {{ sessionId: string, feature: string, phase: string, hooks: Array, skills: Array }|null}
|
|
73
|
-
*/
|
|
74
|
-
export function readActivity(projectPath) {
|
|
75
|
-
try {
|
|
76
|
-
return readRaw(getActivityPath(projectPath));
|
|
77
|
-
} catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Reset the activity log for a new session.
|
|
84
|
-
* Called from SessionStart hook to clear stale data.
|
|
85
|
-
*
|
|
86
|
-
* @param {string} sessionId - ISO timestamp of new session
|
|
87
|
-
* @param {string} feature - Active feature name (empty string if none)
|
|
88
|
-
* @param {string} phase - Current phase (empty string if none)
|
|
89
|
-
* @param {string} [projectPath]
|
|
90
|
-
*/
|
|
91
|
-
export function resetActivity(sessionId, feature, phase, projectPath) {
|
|
92
|
-
try {
|
|
93
|
-
ensureLogsDir(projectPath);
|
|
94
|
-
const data = {
|
|
95
|
-
sessionId: sessionId || new Date().toISOString(),
|
|
96
|
-
feature: feature || '',
|
|
97
|
-
phase: phase || '',
|
|
98
|
-
hooks: [],
|
|
99
|
-
skills: []
|
|
100
|
-
};
|
|
101
|
-
writeFileSync(getActivityPath(projectPath), JSON.stringify(data, null, 2), 'utf-8');
|
|
102
|
-
} catch {
|
|
103
|
-
// Fail-silent
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Log a structured event to the session activity log.
|
|
109
|
-
*
|
|
110
|
-
* @param {string} type - Event type (e.g., 'task_start', 'loop_detected')
|
|
111
|
-
* @param {Object} data - Event data payload
|
|
112
|
-
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
113
|
-
*/
|
|
114
|
-
export function logEvent(type, data, projectPath) {
|
|
115
|
-
try {
|
|
116
|
-
const activityPath = getActivityPath(projectPath);
|
|
117
|
-
ensureLogsDir(projectPath);
|
|
118
|
-
|
|
119
|
-
const now = new Date();
|
|
120
|
-
const ts = now.toTimeString().slice(0, 8); // HH:MM:SS
|
|
121
|
-
|
|
122
|
-
const activity = readRaw(activityPath) || { sessionId: '', feature: '', phase: '', hooks: [], events: [] };
|
|
123
|
-
activity.events = activity.events || [];
|
|
124
|
-
activity.events.push({ type, data, ts });
|
|
125
|
-
|
|
126
|
-
writeFileSync(activityPath, JSON.stringify(activity, null, 2), 'utf-8');
|
|
127
|
-
} catch {
|
|
128
|
-
// Fail-silent
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Archive current activity.json to sessions/ directory for historical logging.
|
|
134
|
-
* Called at the start of a new session.
|
|
135
|
-
*
|
|
136
|
-
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
137
|
-
*/
|
|
138
|
-
export function archiveSession(projectPath) {
|
|
139
|
-
try {
|
|
140
|
-
const activityPath = getActivityPath(projectPath);
|
|
141
|
-
if (!existsSync(activityPath)) return;
|
|
142
|
-
|
|
143
|
-
const data = readRaw(activityPath);
|
|
144
|
-
if (!data) return;
|
|
145
|
-
|
|
146
|
-
// Only archive if there are meaningful events
|
|
147
|
-
if ((!data.hooks || data.hooks.length === 0) && (!data.events || data.events.length === 0)) return;
|
|
148
|
-
|
|
149
|
-
const sessionsDir = join(projectPath || process.cwd(), LOGS_DIR, 'sessions');
|
|
150
|
-
mkdirSync(sessionsDir, { recursive: true });
|
|
151
|
-
|
|
152
|
-
const sessionId = (data.sessionId || new Date().toISOString()).replace(/[:.]/g, '-');
|
|
153
|
-
const archivePath = join(sessionsDir, `${sessionId}.json`);
|
|
154
|
-
writeFileSync(archivePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
155
|
-
|
|
156
|
-
unlinkSync(activityPath);
|
|
157
|
-
} catch {
|
|
158
|
-
// Fail-silent
|
|
159
|
-
}
|
|
160
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Activity Logger — Session-scoped hook event log
|
|
3
|
+
*
|
|
4
|
+
* Writes hook activity to .morph/logs/activity.json for live consumption
|
|
5
|
+
* by `morph-spec monitor`.
|
|
6
|
+
*
|
|
7
|
+
* Design constraints:
|
|
8
|
+
* - Synchronous only (hooks run in process, no async overhead)
|
|
9
|
+
* - Fail-silent (never throws — hooks must not be blocked by logger)
|
|
10
|
+
* - ≤5ms per call (no retries, no network)
|
|
11
|
+
* - Windows-safe paths via path.join
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
|
|
17
|
+
const LOGS_DIR = '.morph/logs';
|
|
18
|
+
const ACTIVITY_FILE = join(LOGS_DIR, 'activity.json');
|
|
19
|
+
|
|
20
|
+
function getActivityPath(projectPath) {
|
|
21
|
+
return join(projectPath || process.cwd(), ACTIVITY_FILE);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function ensureLogsDir(projectPath) {
|
|
25
|
+
const dir = join(projectPath || process.cwd(), LOGS_DIR);
|
|
26
|
+
if (!existsSync(dir)) {
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readRaw(activityPath) {
|
|
32
|
+
try {
|
|
33
|
+
if (!existsSync(activityPath)) return null;
|
|
34
|
+
return JSON.parse(readFileSync(activityPath, 'utf-8'));
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Log a hook firing event to the session activity log.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} name - Hook name (e.g. 'dispatch.js', 'enrich-prompt')
|
|
44
|
+
* @param {string} event - Claude Code event (e.g. 'PostToolUse', 'UserPromptSubmit')
|
|
45
|
+
* @param {string} result - Outcome summary (e.g. 'ok', 'blocked', 'checkpoint_saved')
|
|
46
|
+
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
47
|
+
*/
|
|
48
|
+
export function logHookActivity(name, event, result, projectPath) {
|
|
49
|
+
try {
|
|
50
|
+
const activityPath = getActivityPath(projectPath);
|
|
51
|
+
ensureLogsDir(projectPath);
|
|
52
|
+
|
|
53
|
+
const now = new Date();
|
|
54
|
+
const ts = now.toTimeString().slice(0, 8); // HH:MM:SS
|
|
55
|
+
|
|
56
|
+
const data = readRaw(activityPath) || { sessionId: '', feature: '', phase: '', hooks: [], skills: [] };
|
|
57
|
+
|
|
58
|
+
data.hooks = data.hooks || [];
|
|
59
|
+
data.hooks.push({ name, event, result, ts });
|
|
60
|
+
|
|
61
|
+
writeFileSync(activityPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
62
|
+
} catch {
|
|
63
|
+
// Fail-silent — never block hooks
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Read the current activity log.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} [projectPath]
|
|
72
|
+
* @returns {{ sessionId: string, feature: string, phase: string, hooks: Array, skills: Array }|null}
|
|
73
|
+
*/
|
|
74
|
+
export function readActivity(projectPath) {
|
|
75
|
+
try {
|
|
76
|
+
return readRaw(getActivityPath(projectPath));
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Reset the activity log for a new session.
|
|
84
|
+
* Called from SessionStart hook to clear stale data.
|
|
85
|
+
*
|
|
86
|
+
* @param {string} sessionId - ISO timestamp of new session
|
|
87
|
+
* @param {string} feature - Active feature name (empty string if none)
|
|
88
|
+
* @param {string} phase - Current phase (empty string if none)
|
|
89
|
+
* @param {string} [projectPath]
|
|
90
|
+
*/
|
|
91
|
+
export function resetActivity(sessionId, feature, phase, projectPath) {
|
|
92
|
+
try {
|
|
93
|
+
ensureLogsDir(projectPath);
|
|
94
|
+
const data = {
|
|
95
|
+
sessionId: sessionId || new Date().toISOString(),
|
|
96
|
+
feature: feature || '',
|
|
97
|
+
phase: phase || '',
|
|
98
|
+
hooks: [],
|
|
99
|
+
skills: []
|
|
100
|
+
};
|
|
101
|
+
writeFileSync(getActivityPath(projectPath), JSON.stringify(data, null, 2), 'utf-8');
|
|
102
|
+
} catch {
|
|
103
|
+
// Fail-silent
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Log a structured event to the session activity log.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} type - Event type (e.g., 'task_start', 'loop_detected')
|
|
111
|
+
* @param {Object} data - Event data payload
|
|
112
|
+
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
113
|
+
*/
|
|
114
|
+
export function logEvent(type, data, projectPath) {
|
|
115
|
+
try {
|
|
116
|
+
const activityPath = getActivityPath(projectPath);
|
|
117
|
+
ensureLogsDir(projectPath);
|
|
118
|
+
|
|
119
|
+
const now = new Date();
|
|
120
|
+
const ts = now.toTimeString().slice(0, 8); // HH:MM:SS
|
|
121
|
+
|
|
122
|
+
const activity = readRaw(activityPath) || { sessionId: '', feature: '', phase: '', hooks: [], events: [] };
|
|
123
|
+
activity.events = activity.events || [];
|
|
124
|
+
activity.events.push({ type, data, ts });
|
|
125
|
+
|
|
126
|
+
writeFileSync(activityPath, JSON.stringify(activity, null, 2), 'utf-8');
|
|
127
|
+
} catch {
|
|
128
|
+
// Fail-silent
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Archive current activity.json to sessions/ directory for historical logging.
|
|
134
|
+
* Called at the start of a new session.
|
|
135
|
+
*
|
|
136
|
+
* @param {string} [projectPath] - Project root (defaults to cwd)
|
|
137
|
+
*/
|
|
138
|
+
export function archiveSession(projectPath) {
|
|
139
|
+
try {
|
|
140
|
+
const activityPath = getActivityPath(projectPath);
|
|
141
|
+
if (!existsSync(activityPath)) return;
|
|
142
|
+
|
|
143
|
+
const data = readRaw(activityPath);
|
|
144
|
+
if (!data) return;
|
|
145
|
+
|
|
146
|
+
// Only archive if there are meaningful events
|
|
147
|
+
if ((!data.hooks || data.hooks.length === 0) && (!data.events || data.events.length === 0)) return;
|
|
148
|
+
|
|
149
|
+
const sessionsDir = join(projectPath || process.cwd(), LOGS_DIR, 'sessions');
|
|
150
|
+
mkdirSync(sessionsDir, { recursive: true });
|
|
151
|
+
|
|
152
|
+
const sessionId = (data.sessionId || new Date().toISOString()).replace(/[:.]/g, '-');
|
|
153
|
+
const archivePath = join(sessionsDir, `${sessionId}.json`);
|
|
154
|
+
writeFileSync(archivePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
155
|
+
|
|
156
|
+
unlinkSync(activityPath);
|
|
157
|
+
} catch {
|
|
158
|
+
// Fail-silent
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared stdin reader for Claude Code hooks.
|
|
3
|
-
*
|
|
4
|
-
* Reads JSON payload from stdin (provided by Claude Code to hooks).
|
|
5
|
-
* Returns parsed object or null on failure.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Read and parse JSON from stdin
|
|
10
|
-
* @returns {Promise<Object|null>} Parsed JSON or null
|
|
11
|
-
*/
|
|
12
|
-
export function readStdin() {
|
|
13
|
-
return new Promise((resolve) => {
|
|
14
|
-
let input = '';
|
|
15
|
-
process.stdin.setEncoding('utf-8');
|
|
16
|
-
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
17
|
-
process.stdin.on('end', () => {
|
|
18
|
-
try {
|
|
19
|
-
resolve(JSON.parse(input || '{}'));
|
|
20
|
-
} catch {
|
|
21
|
-
resolve(null);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
process.stdin.on('error', () => resolve(null));
|
|
25
|
-
});
|
|
26
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared stdin reader for Claude Code hooks.
|
|
3
|
+
*
|
|
4
|
+
* Reads JSON payload from stdin (provided by Claude Code to hooks).
|
|
5
|
+
* Returns parsed object or null on failure.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read and parse JSON from stdin
|
|
10
|
+
* @returns {Promise<Object|null>} Parsed JSON or null
|
|
11
|
+
*/
|
|
12
|
+
export function readStdin() {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
let input = '';
|
|
15
|
+
process.stdin.setEncoding('utf-8');
|
|
16
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
17
|
+
process.stdin.on('end', () => {
|
|
18
|
+
try {
|
|
19
|
+
resolve(JSON.parse(input || '{}'));
|
|
20
|
+
} catch {
|
|
21
|
+
resolve(null);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
process.stdin.on('error', () => resolve(null));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "backend",
|
|
3
|
-
"version": "1.1.0",
|
|
4
|
-
"description": "Backend-focused rubric. Higher weight on architecture, security, and package health. Deterministic-validator rubric — approve threshold aligned to the single bar 9 from MORPH.md §0.",
|
|
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": 9.0,
|
|
39
|
-
"retry": 6.0
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "backend",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Backend-focused rubric. Higher weight on architecture, security, and package health. Deterministic-validator rubric — approve threshold aligned to the single bar 9 from MORPH.md §0.",
|
|
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": 9.0,
|
|
39
|
+
"retry": 6.0
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,45 +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
|
-
> **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) |
|
|
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) |
|