@polymorphism-tech/morph-spec 8.44.0 โ 8.46.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/CLAUDE.md +11 -9
- package/README.md +10 -10
- package/bin/morph-spec.js +11 -13
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +2 -4
- package/docs/QUICKSTART.md +6 -6
- package/framework/CLAUDE.md +6 -8
- package/framework/MORPH.md +39 -45
- package/framework/agents.json +8 -9
- package/framework/commands/morph-apply.md +1 -3
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/commands/morph-proposal.md +2 -2
- package/framework/docs/CLI.md +15 -14
- package/framework/evals/review-checklist.md +90 -0
- package/framework/evals/trace-schema.md +2 -12
- package/framework/hooks/README.md +2 -3
- package/framework/hooks/claude-code/core/heavy-gate.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +2 -2
- package/framework/hooks/claude-code/core/telemetry-log.js +2 -2
- package/framework/hooks/claude-code/core/trace-autogen.js +1 -22
- package/framework/hooks/claude-code/core/validate-completion.js +3 -56
- 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/build-check.js +1 -1
- package/framework/hooks/shared/comment-scanner.js +1 -1
- package/framework/hooks/shared/phase-utils.js +0 -5
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/phases.json +4 -6
- package/framework/rubrics/backend.json +1 -1
- package/framework/rubrics/default.json +1 -1
- package/framework/rubrics/frontend.json +1 -1
- package/framework/rules/morph-workflow.md +6 -6
- package/framework/schemas/config.schema.json +4 -0
- package/framework/schemas/feature.schema.json +5 -29
- package/framework/schemas/tasks.schema.json +6 -2
- package/framework/skills/README.md +1 -2
- 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 +145 -246
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +5 -3
- package/framework/skills/core/morph-implement/SKILL.md +101 -201
- package/framework/skills/core/morph-machine/SKILL.md +3 -3
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +171 -287
- package/framework/skills/core/morph-proposal/SKILL.md +4 -5
- package/framework/skills/core/morph-review/SKILL.md +122 -430
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +2 -2
- package/framework/skills/core/morph-uiux/SKILL.md +2 -3
- package/framework/standards/STANDARDS.json +10 -10
- package/framework/standards/ai-agents/agent-archetypes.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/agent-spec.md +1 -1
- package/framework/standards/ai-agents/batching.md +1 -1
- package/framework/standards/ai-agents/context-providers.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +1 -1
- package/framework/standards/ai-agents/cost-and-budget.md +1 -1
- package/framework/standards/ai-agents/durable-workflows-hitl.md +1 -1
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
- package/framework/standards/ai-agents/mcp-server.md +1 -1
- package/framework/standards/ai-agents/mcp-tools.md +1 -1
- package/framework/standards/ai-agents/media-pipeline.md +1 -1
- package/framework/standards/ai-agents/media-video.md +1 -1
- package/framework/standards/ai-agents/middleware-patterns.md +1 -1
- package/framework/standards/ai-agents/modalities-image-gen.md +1 -1
- package/framework/standards/ai-agents/modalities-speech-to-text.md +1 -1
- package/framework/standards/ai-agents/modalities-text-to-speech.md +1 -1
- package/framework/standards/ai-agents/modalities-vision.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +1 -1
- package/framework/standards/ai-agents/observability-patterns.md +3 -3
- package/framework/standards/ai-agents/production.md +2 -2
- package/framework/standards/ai-agents/prompt-sources.md +1 -1
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +1 -1
- package/framework/standards/ai-agents/service-tier-flex.md +1 -1
- package/framework/standards/ai-agents/setup.md +1 -1
- package/framework/standards/ai-agents/structured-output.md +1 -1
- package/framework/standards/ai-agents/sweet-spot.md +1 -1
- package/framework/standards/ai-agents/testing-ai.md +1 -1
- package/framework/standards/ai-agents/tool-adapters.md +1 -1
- package/framework/standards/ai-agents/vector-data-extensions.md +1 -1
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/templates/CLAUDE.md.core.template +1 -1
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/README.md +1 -1
- package/framework/templates/REGISTRY.json +0 -81
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- 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/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/docs/spec.md +19 -205
- 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/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- 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/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/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +2 -2
- package/src/commands/e2e/e2e.js +1 -1
- package/src/commands/project/heavy.js +1 -1
- package/src/commands/project/status.js +3 -3
- package/src/commands/state/approve.js +7 -49
- package/src/commands/state/gate-check.js +16 -106
- package/src/commands/state/gate-decision.js +1 -1
- package/src/commands/state/report-check.js +42 -17
- package/src/commands/validation/mutate.js +1 -1
- package/src/commands/validation/scout-check.js +28 -0
- package/src/commands/validation/validate-feature.js +5 -32
- package/src/commands/validation/verify.js +98 -48
- package/src/core/paths/output-schema.js +0 -2
- package/src/core/state/state-manager.js +1 -2
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/lib/format.js +5 -0
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/FeatureDetail.jsx +16 -22
- package/src/dashboard/app/pages/Features.jsx +7 -7
- package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
- package/src/dashboard/app/pages/Rubrics.jsx +7 -11
- package/src/dashboard/scanner/docs-scanner.js +1 -2
- package/src/dashboard/scanner/features-scanner.js +3 -4
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/output-collector.js +0 -1
- package/src/lib/ci/ci-verify.js +118 -0
- package/src/lib/ci/github-ci.js +192 -0
- package/src/lib/ci/workflow-scaffold.js +122 -0
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/evaluator-report.js +52 -334
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/handoff-generator.js +4 -5
- package/src/lib/installers/memory-installer.js +2 -2
- package/src/lib/mutation/manifest.js +8 -2
- package/src/lib/mutation/report.js +5 -3
- package/src/lib/mutation/runner.js +9 -7
- package/src/lib/risk-detector.js +60 -122
- package/src/lib/scout/scout-check.js +293 -0
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/tasks-json-parser.js +7 -5
- package/src/lib/tasks/test-nodes.js +1 -1
- package/src/lib/tasks/test-runner.js +1 -1
- package/src/lib/telemetry/verify-event.js +3 -2
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/reuse/reuse-validator.js +6 -8
- package/src/lib/validators/verify-runner.js +1 -1
- package/src/scripts/setup-infra.js +1 -1
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +5 -9
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/hooks-installer.js +3 -10
- package/src/utils/skills-installer.js +1 -1
- package/framework/evals/proof-rubrics/README.md +0 -76
- package/framework/evals/proof-rubrics/eval-de-modelo.md +0 -80
- package/framework/evals/proof-rubrics/fiacao.md +0 -54
- package/framework/evals/proof-rubrics/guard-cego.md +0 -52
- package/framework/evals/proof-rubrics/media-claims.md +0 -109
- package/framework/evals/proof-rubrics/mutation-proof.md +0 -107
- package/framework/evals/proof-rubrics/observabilidade-genai.md +0 -119
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +0 -48
- package/framework/evals/rubrics/README.md +0 -45
- package/framework/evals/rubrics/architecture.md +0 -103
- package/framework/evals/rubrics/code-quality.md +0 -98
- package/framework/evals/rubrics/condensed.md +0 -57
- package/framework/evals/rubrics/contracts.md +0 -67
- package/framework/evals/rubrics/test-coverage.md +0 -99
- package/framework/evals/scenarios/dotnet-crud.yaml +0 -42
- package/framework/evals/scenarios/nextjs-auth.yaml +0 -38
- package/framework/evals/suites/standard.yaml +0 -5
- package/framework/hooks/claude-code/__pycache__/statusline.cpython-313.pyc +0 -0
- package/framework/hooks/claude-code/core/post-edit-typecheck.js +0 -127
- package/framework/skills/core/morph-eval/SKILL.md +0 -64
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/framework/templates/docs/clarifications.md +0 -253
- package/framework/templates/docs/onboarding.md +0 -122
- package/framework/templates/docs/schema-analysis.md +0 -119
- package/framework/templates/docs/user-stories.md +0 -34
- package/src/commands/state/score.js +0 -147
|
@@ -1,30 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Stop Hook:
|
|
5
|
-
*
|
|
6
|
-
* Event: Stop
|
|
7
|
-
*
|
|
8
|
-
* 1. Detects transitions into the `implement` phase and recommends /compact.
|
|
9
|
-
* 2. Runs stack-aware build check โ dirty-flag gated (R1.2), warns only on
|
|
10
|
-
* failure (silent on pass/skip).
|
|
4
|
+
* Stop Hook: phase-transition alert, recap/tasks audit, session usage.
|
|
11
5
|
*
|
|
12
6
|
* Phase transition tracking: stores last-seen phase per feature in
|
|
13
7
|
* .morph/memory/phase-watch.json so the alert fires exactly once.
|
|
14
8
|
*
|
|
15
|
-
* Build-dirty gate: post-edit-typecheck.js touches
|
|
16
|
-
* .morph/memory/build-dirty.json on every source-file Write/Edit. Without
|
|
17
|
-
* that flag nothing changed since the last verified build, so the (often
|
|
18
|
-
* expensive) full build/typecheck is skipped entirely instead of running on
|
|
19
|
-
* every single Stop.
|
|
20
|
-
*
|
|
21
9
|
* Fail-open: exits 0 on any error.
|
|
22
10
|
*/
|
|
23
11
|
|
|
24
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync
|
|
12
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
25
13
|
import { join } from 'path';
|
|
26
14
|
import { createHash } from 'crypto';
|
|
27
|
-
import { runBuildCheck } from '../../shared/build-check.js';
|
|
28
15
|
import {
|
|
29
16
|
stateExists, getActiveFeature, getMostRecentFeature, derivePhaseForFeature,
|
|
30
17
|
} from '../../shared/state-reader.js';
|
|
@@ -154,9 +141,6 @@ export async function run(payload) {
|
|
|
154
141
|
const cwd = process.cwd();
|
|
155
142
|
const warnings = [];
|
|
156
143
|
|
|
157
|
-
// .morph/memory/ hosts phase-watch.json, build-dirty.json (written by
|
|
158
|
-
// post-edit-typecheck.js) and warned-hashes.json โ ensure it exists once,
|
|
159
|
-
// up front, so every write below can assume the dir is there.
|
|
160
144
|
const memDir = join(cwd, '.morph', 'memory');
|
|
161
145
|
try { mkdirSync(memDir, { recursive: true }); } catch { /* non-blocking */ }
|
|
162
146
|
|
|
@@ -187,7 +171,7 @@ export async function run(payload) {
|
|
|
187
171
|
`โก Phase advanced: ${lastPhase} โ implement`,
|
|
188
172
|
``,
|
|
189
173
|
`๐ก Recommended before starting implementation:`,
|
|
190
|
-
` Run /compact to free up context โ spec.md
|
|
174
|
+
` Run /compact to free up context โ spec.md and tasks.json`,
|
|
191
175
|
` loaded during planning take significant space. A compact now gives`,
|
|
192
176
|
` Claude a clean slate focused on writing code.`,
|
|
193
177
|
``,
|
|
@@ -195,43 +179,6 @@ export async function run(payload) {
|
|
|
195
179
|
);
|
|
196
180
|
}
|
|
197
181
|
|
|
198
|
-
// โโ Build/typecheck verification (dirty-flag gated โ R1.2) โโโโโโโโโโโโโโโโ
|
|
199
|
-
// Only run the (often expensive) full build/typecheck when something
|
|
200
|
-
// actually changed since the last time it was verified โ post-edit-
|
|
201
|
-
// typecheck.js sets the flag on every source-file Write/Edit. No flag โ
|
|
202
|
-
// nothing to verify โ skip silently, no config/stack read even attempted.
|
|
203
|
-
const BUILD_CHECK_TIMEOUT_MS = 30000; // per-step timeout โ build-check.js's own default, made explicit here
|
|
204
|
-
try {
|
|
205
|
-
const dirtyFlagPath = join(memDir, 'build-dirty.json');
|
|
206
|
-
if (existsSync(dirtyFlagPath)) {
|
|
207
|
-
const configPath = join(cwd, '.morph', 'config', 'config.json');
|
|
208
|
-
if (existsSync(configPath)) {
|
|
209
|
-
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
210
|
-
const stack = config?.project?.stack;
|
|
211
|
-
const { frontendPath, backendPath } = config?.project ?? {};
|
|
212
|
-
if (stack && currentPhase === 'implement') {
|
|
213
|
-
const buildResult = runBuildCheck(cwd, stack, BUILD_CHECK_TIMEOUT_MS, { frontendPath, backendPath });
|
|
214
|
-
if (buildResult.status === 'fail') {
|
|
215
|
-
warnings.push('โ Build/typecheck failed:');
|
|
216
|
-
warnings.push(buildResult.output);
|
|
217
|
-
warnings.push('Fix build errors before ending session.');
|
|
218
|
-
// keep the dirty flag โ still dirty until a build actually passes
|
|
219
|
-
} else {
|
|
220
|
-
// 'pass' โ verified clean. 'skip' โ no build step was even
|
|
221
|
-
// resolved for this stack (e.g. fresh worktree, no tsconfig) โ
|
|
222
|
-
// nothing to verify, so there is nothing left to stay dirty about.
|
|
223
|
-
// Either way, re-arm on the NEXT source edit, not every Stop.
|
|
224
|
-
try { unlinkSync(dirtyFlagPath); } catch { /* non-blocking */ }
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// No flag โ skip the build entirely, silently.
|
|
230
|
-
} catch {
|
|
231
|
-
// Fail-open โ build check must never block Stop
|
|
232
|
-
}
|
|
233
|
-
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
234
|
-
|
|
235
182
|
// โโ Recap + tasks.json audit โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
236
183
|
// Surface drift between recap.md and tasks.json, plus missing standard
|
|
237
184
|
// citations. Advisory warnings only โ Stop hook never blocks.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# morph-spec statusline โ installed globally to ~/.claude/statusline.sh
|
|
3
|
-
# Claude Code invokes this with JSON via stdin after each response.
|
|
4
|
-
# Requires: Python 3 available as `python3` or `python` on PATH.
|
|
5
|
-
|
|
6
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
if command -v python3 &>/dev/null; then
|
|
8
|
-
python3 "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
9
|
-
elif command -v python &>/dev/null; then
|
|
10
|
-
python "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
11
|
-
fi
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# morph-spec statusline โ installed globally to ~/.claude/statusline.sh
|
|
3
|
+
# Claude Code invokes this with JSON via stdin after each response.
|
|
4
|
+
# Requires: Python 3 available as `python3` or `python` on PATH.
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
if command -v python3 &>/dev/null; then
|
|
8
|
+
python3 "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
9
|
+
elif command -v python &>/dev/null; then
|
|
10
|
+
python "${SCRIPT_DIR}/statusline.py" 2>/dev/null || true
|
|
11
|
+
fi
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Scope: universal | Validates commit message format (Conventional Commits)
|
|
3
|
-
# MORPH-SPEC Commit Message Hook
|
|
4
|
-
# Enforces Conventional Commits specification
|
|
5
|
-
|
|
6
|
-
COMMIT_MSG_FILE="$1"
|
|
7
|
-
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
8
|
-
|
|
9
|
-
# Conventional Commits pattern: type(scope): description
|
|
10
|
-
# Types: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert
|
|
11
|
-
PATTERN="^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\(.+\))?: .{1,100}"
|
|
12
|
-
|
|
13
|
-
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
|
|
14
|
-
echo "โ Invalid commit message format!"
|
|
15
|
-
echo ""
|
|
16
|
-
echo "Required format: <type>(<scope>): <description>"
|
|
17
|
-
echo ""
|
|
18
|
-
echo "Types: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert"
|
|
19
|
-
echo ""
|
|
20
|
-
echo "Examples:"
|
|
21
|
-
echo " feat(auth): add JWT refresh token rotation"
|
|
22
|
-
echo " fix(api): resolve null reference in UserService"
|
|
23
|
-
echo " docs(readme): update installation instructions"
|
|
24
|
-
echo ""
|
|
25
|
-
echo "Your message:"
|
|
26
|
-
echo " $COMMIT_MSG"
|
|
27
|
-
echo ""
|
|
28
|
-
echo "Override with: git commit --no-verify"
|
|
29
|
-
exit 1
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
echo "โ
Commit message format valid"
|
|
33
|
-
exit 0
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Scope: universal | Validates commit message format (Conventional Commits)
|
|
3
|
+
# MORPH-SPEC Commit Message Hook
|
|
4
|
+
# Enforces Conventional Commits specification
|
|
5
|
+
|
|
6
|
+
COMMIT_MSG_FILE="$1"
|
|
7
|
+
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
8
|
+
|
|
9
|
+
# Conventional Commits pattern: type(scope): description
|
|
10
|
+
# Types: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert
|
|
11
|
+
PATTERN="^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\(.+\))?: .{1,100}"
|
|
12
|
+
|
|
13
|
+
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
|
|
14
|
+
echo "โ Invalid commit message format!"
|
|
15
|
+
echo ""
|
|
16
|
+
echo "Required format: <type>(<scope>): <description>"
|
|
17
|
+
echo ""
|
|
18
|
+
echo "Types: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Examples:"
|
|
21
|
+
echo " feat(auth): add JWT refresh token rotation"
|
|
22
|
+
echo " fix(api): resolve null reference in UserService"
|
|
23
|
+
echo " docs(readme): update installation instructions"
|
|
24
|
+
echo ""
|
|
25
|
+
echo "Your message:"
|
|
26
|
+
echo " $COMMIT_MSG"
|
|
27
|
+
echo ""
|
|
28
|
+
echo "Override with: git commit --no-verify"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
echo "โ
Commit message format valid"
|
|
33
|
+
exit 0
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Scope: universal | Validates agents.json Schema
|
|
3
|
-
# MORPH-SPEC Pre-Commit Hook: Agent Configuration Validation
|
|
4
|
-
# Uses validate-agents.js to check agents.json
|
|
5
|
-
|
|
6
|
-
echo "๐ค Validating agent configuration..."
|
|
7
|
-
|
|
8
|
-
# Check if agents.json is being modified
|
|
9
|
-
if git diff --cached --name-only | grep -q 'agents\.json$'; then
|
|
10
|
-
echo "Detected changes to agents.json"
|
|
11
|
-
|
|
12
|
-
# Run validator
|
|
13
|
-
if ! morph-spec validate-agents-skills; then
|
|
14
|
-
echo ""
|
|
15
|
-
echo "โ COMMIT BLOCKED: agents.json validation failed"
|
|
16
|
-
echo " Fix errors above before committing"
|
|
17
|
-
exit 1
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
echo "โ agents.json is valid"
|
|
21
|
-
else
|
|
22
|
-
echo "โ No changes to agents.json"
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
exit 0
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Scope: universal | Validates agents.json Schema
|
|
3
|
+
# MORPH-SPEC Pre-Commit Hook: Agent Configuration Validation
|
|
4
|
+
# Uses validate-agents.js to check agents.json
|
|
5
|
+
|
|
6
|
+
echo "๐ค Validating agent configuration..."
|
|
7
|
+
|
|
8
|
+
# Check if agents.json is being modified
|
|
9
|
+
if git diff --cached --name-only | grep -q 'agents\.json$'; then
|
|
10
|
+
echo "Detected changes to agents.json"
|
|
11
|
+
|
|
12
|
+
# Run validator
|
|
13
|
+
if ! morph-spec validate-agents-skills; then
|
|
14
|
+
echo ""
|
|
15
|
+
echo "โ COMMIT BLOCKED: agents.json validation failed"
|
|
16
|
+
echo " Fix errors above before committing"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
echo "โ agents.json is valid"
|
|
21
|
+
else
|
|
22
|
+
echo "โ No changes to agents.json"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
exit 0
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Scope: universal | Orchestrates framework + stack-specific pre-commit hooks
|
|
3
|
-
# MORPH-SPEC Master Pre-Commit Hook
|
|
4
|
-
# Runs universal framework hooks + stack-specific hooks in sequence
|
|
5
|
-
|
|
6
|
-
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
7
|
-
echo "โ MORPH-SPEC PRE-COMMIT VALIDATION โ"
|
|
8
|
-
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
9
|
-
echo ""
|
|
10
|
-
|
|
11
|
-
FRAMEWORK_HOOKS_DIR="$(dirname "$0")"
|
|
12
|
-
STACK_HOOKS_DIR=".morph/hooks/pre-commit"
|
|
13
|
-
|
|
14
|
-
HAS_FAILURES=false
|
|
15
|
-
|
|
16
|
-
# Run framework hooks (universal - all stacks)
|
|
17
|
-
echo "๐ฆ Running framework hooks (universal)..."
|
|
18
|
-
for hook in "$FRAMEWORK_HOOKS_DIR"/*.sh; do
|
|
19
|
-
# Skip orchestrator itself
|
|
20
|
-
if [[ "$hook" == */orchestrator.sh ]]; then
|
|
21
|
-
continue
|
|
22
|
-
fi
|
|
23
|
-
|
|
24
|
-
if [[ -f "$hook" ]]; then
|
|
25
|
-
hook_name=$(basename "$hook")
|
|
26
|
-
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
27
|
-
if ! bash "$hook"; then
|
|
28
|
-
HAS_FAILURES=true
|
|
29
|
-
echo "โ Framework hook failed: $hook_name"
|
|
30
|
-
fi
|
|
31
|
-
echo ""
|
|
32
|
-
fi
|
|
33
|
-
done
|
|
34
|
-
|
|
35
|
-
# Run stack-specific hooks (if exist)
|
|
36
|
-
if [[ -d "$STACK_HOOKS_DIR" ]]; then
|
|
37
|
-
echo "๐ฏ Running stack-specific hooks..."
|
|
38
|
-
for hook in "$STACK_HOOKS_DIR"/*.sh; do
|
|
39
|
-
if [[ -f "$hook" ]]; then
|
|
40
|
-
hook_name=$(basename "$hook")
|
|
41
|
-
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
42
|
-
if ! bash "$hook"; then
|
|
43
|
-
HAS_FAILURES=true
|
|
44
|
-
echo "โ Stack hook failed: $hook_name"
|
|
45
|
-
fi
|
|
46
|
-
echo ""
|
|
47
|
-
fi
|
|
48
|
-
done
|
|
49
|
-
else
|
|
50
|
-
echo "โน๏ธ No stack-specific hooks found (optional)"
|
|
51
|
-
echo ""
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
55
|
-
|
|
56
|
-
if [[ "$HAS_FAILURES" == "true" ]]; then
|
|
57
|
-
echo "โ PRE-COMMIT VALIDATION FAILED"
|
|
58
|
-
echo " Fix errors above before committing"
|
|
59
|
-
echo " Or use: git commit --no-verify to skip"
|
|
60
|
-
exit 1
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
echo "โ
ALL PRE-COMMIT VALIDATIONS PASSED"
|
|
64
|
-
exit 0
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Scope: universal | Orchestrates framework + stack-specific pre-commit hooks
|
|
3
|
+
# MORPH-SPEC Master Pre-Commit Hook
|
|
4
|
+
# Runs universal framework hooks + stack-specific hooks in sequence
|
|
5
|
+
|
|
6
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
7
|
+
echo "โ MORPH-SPEC PRE-COMMIT VALIDATION โ"
|
|
8
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
FRAMEWORK_HOOKS_DIR="$(dirname "$0")"
|
|
12
|
+
STACK_HOOKS_DIR=".morph/hooks/pre-commit"
|
|
13
|
+
|
|
14
|
+
HAS_FAILURES=false
|
|
15
|
+
|
|
16
|
+
# Run framework hooks (universal - all stacks)
|
|
17
|
+
echo "๐ฆ Running framework hooks (universal)..."
|
|
18
|
+
for hook in "$FRAMEWORK_HOOKS_DIR"/*.sh; do
|
|
19
|
+
# Skip orchestrator itself
|
|
20
|
+
if [[ "$hook" == */orchestrator.sh ]]; then
|
|
21
|
+
continue
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
if [[ -f "$hook" ]]; then
|
|
25
|
+
hook_name=$(basename "$hook")
|
|
26
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
27
|
+
if ! bash "$hook"; then
|
|
28
|
+
HAS_FAILURES=true
|
|
29
|
+
echo "โ Framework hook failed: $hook_name"
|
|
30
|
+
fi
|
|
31
|
+
echo ""
|
|
32
|
+
fi
|
|
33
|
+
done
|
|
34
|
+
|
|
35
|
+
# Run stack-specific hooks (if exist)
|
|
36
|
+
if [[ -d "$STACK_HOOKS_DIR" ]]; then
|
|
37
|
+
echo "๐ฏ Running stack-specific hooks..."
|
|
38
|
+
for hook in "$STACK_HOOKS_DIR"/*.sh; do
|
|
39
|
+
if [[ -f "$hook" ]]; then
|
|
40
|
+
hook_name=$(basename "$hook")
|
|
41
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
42
|
+
if ! bash "$hook"; then
|
|
43
|
+
HAS_FAILURES=true
|
|
44
|
+
echo "โ Stack hook failed: $hook_name"
|
|
45
|
+
fi
|
|
46
|
+
echo ""
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
else
|
|
50
|
+
echo "โน๏ธ No stack-specific hooks found (optional)"
|
|
51
|
+
echo ""
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
55
|
+
|
|
56
|
+
if [[ "$HAS_FAILURES" == "true" ]]; then
|
|
57
|
+
echo "โ PRE-COMMIT VALIDATION FAILED"
|
|
58
|
+
echo " Fix errors above before committing"
|
|
59
|
+
echo " Or use: git commit --no-verify to skip"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo "โ
ALL PRE-COMMIT VALIDATIONS PASSED"
|
|
64
|
+
exit 0
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Scope: universal | Validates spec.md required sections
|
|
3
|
-
# MORPH-SPEC Pre-Commit Hook: Spec Validation
|
|
4
|
-
# Validates that spec.md files have required sections
|
|
5
|
-
|
|
6
|
-
echo "๐ Validating spec files..."
|
|
7
|
-
|
|
8
|
-
# Find modified spec.md files
|
|
9
|
-
SPEC_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep 'spec\.md$')
|
|
10
|
-
|
|
11
|
-
if [ -z "$SPEC_FILES" ]; then
|
|
12
|
-
echo "โ No spec files modified"
|
|
13
|
-
exit 0
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
HAS_ERRORS=false
|
|
17
|
-
|
|
18
|
-
for spec_file in $SPEC_FILES; do
|
|
19
|
-
echo "Checking: $spec_file"
|
|
20
|
-
|
|
21
|
-
# Required sections
|
|
22
|
-
REQUIRED_SECTIONS=(
|
|
23
|
-
"## ๐ Metadata"
|
|
24
|
-
"## ๐ฏ Overview"
|
|
25
|
-
"## ๐๏ธ Technical Design"
|
|
26
|
-
"## โ
Acceptance Criteria"
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
for section in "${REQUIRED_SECTIONS[@]}"; do
|
|
30
|
-
if ! grep -q "$section" "$spec_file"; then
|
|
31
|
-
echo " โ Missing section: $section"
|
|
32
|
-
HAS_ERRORS=true
|
|
33
|
-
fi
|
|
34
|
-
done
|
|
35
|
-
|
|
36
|
-
# Check if has at least one user story or requirement
|
|
37
|
-
if ! grep -qi "user story\|requirement\|acceptance criteria" "$spec_file"; then
|
|
38
|
-
echo " โ ๏ธ Warning: No user stories or requirements found"
|
|
39
|
-
fi
|
|
40
|
-
done
|
|
41
|
-
|
|
42
|
-
if [ "$HAS_ERRORS" = true ]; then
|
|
43
|
-
echo ""
|
|
44
|
-
echo "โ COMMIT BLOCKED: spec.md files are incomplete"
|
|
45
|
-
echo " Add missing sections before committing"
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
echo "โ All spec files are valid"
|
|
50
|
-
exit 0
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Scope: universal | Validates spec.md required sections
|
|
3
|
+
# MORPH-SPEC Pre-Commit Hook: Spec Validation
|
|
4
|
+
# Validates that spec.md files have required sections
|
|
5
|
+
|
|
6
|
+
echo "๐ Validating spec files..."
|
|
7
|
+
|
|
8
|
+
# Find modified spec.md files
|
|
9
|
+
SPEC_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep 'spec\.md$')
|
|
10
|
+
|
|
11
|
+
if [ -z "$SPEC_FILES" ]; then
|
|
12
|
+
echo "โ No spec files modified"
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
HAS_ERRORS=false
|
|
17
|
+
|
|
18
|
+
for spec_file in $SPEC_FILES; do
|
|
19
|
+
echo "Checking: $spec_file"
|
|
20
|
+
|
|
21
|
+
# Required sections
|
|
22
|
+
REQUIRED_SECTIONS=(
|
|
23
|
+
"## ๐ Metadata"
|
|
24
|
+
"## ๐ฏ Overview"
|
|
25
|
+
"## ๐๏ธ Technical Design"
|
|
26
|
+
"## โ
Acceptance Criteria"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
for section in "${REQUIRED_SECTIONS[@]}"; do
|
|
30
|
+
if ! grep -q "$section" "$spec_file"; then
|
|
31
|
+
echo " โ Missing section: $section"
|
|
32
|
+
HAS_ERRORS=true
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
# Check if has at least one user story or requirement
|
|
37
|
+
if ! grep -qi "user story\|requirement\|acceptance criteria" "$spec_file"; then
|
|
38
|
+
echo " โ ๏ธ Warning: No user stories or requirements found"
|
|
39
|
+
fi
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
if [ "$HAS_ERRORS" = true ]; then
|
|
43
|
+
echo ""
|
|
44
|
+
echo "โ COMMIT BLOCKED: spec.md files are incomplete"
|
|
45
|
+
echo " Add missing sections before committing"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo "โ All spec files are valid"
|
|
50
|
+
exit 0
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Scope: universal | Runs test suite before push
|
|
3
|
-
# MORPH-SPEC Pre-Push Hook
|
|
4
|
-
# Ensures all tests pass before pushing to remote
|
|
5
|
-
|
|
6
|
-
echo "๐งช Running test suite before push..."
|
|
7
|
-
echo ""
|
|
8
|
-
|
|
9
|
-
# Detect project type and run appropriate tests
|
|
10
|
-
if [[ -f *.csproj ]] || find . -maxdepth 2 -name "*.csproj" 2>/dev/null | grep -q .; then
|
|
11
|
-
# .NET project detected
|
|
12
|
-
echo "๐ฆ Detected .NET project"
|
|
13
|
-
|
|
14
|
-
if ! dotnet test --verbosity minimal --no-build --no-restore 2>/dev/null; then
|
|
15
|
-
echo ""
|
|
16
|
-
echo "โ .NET tests failed!"
|
|
17
|
-
echo ""
|
|
18
|
-
echo "Fix failing tests before pushing."
|
|
19
|
-
echo "Override with: git push --no-verify"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
elif [[ -f package.json ]]; then
|
|
24
|
-
# Node.js project detected
|
|
25
|
-
echo "๐ฆ Detected Node.js project"
|
|
26
|
-
|
|
27
|
-
if ! npm test 2>/dev/null; then
|
|
28
|
-
echo ""
|
|
29
|
-
echo "โ Node.js tests failed!"
|
|
30
|
-
echo ""
|
|
31
|
-
echo "Fix failing tests before pushing."
|
|
32
|
-
echo "Override with: git push --no-verify"
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
echo "โ ๏ธ No recognized test framework found"
|
|
38
|
-
echo " Skipping test execution"
|
|
39
|
-
exit 0
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
echo ""
|
|
43
|
-
echo "โ
All tests passed - safe to push"
|
|
44
|
-
exit 0
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Scope: universal | Runs test suite before push
|
|
3
|
+
# MORPH-SPEC Pre-Push Hook
|
|
4
|
+
# Ensures all tests pass before pushing to remote
|
|
5
|
+
|
|
6
|
+
echo "๐งช Running test suite before push..."
|
|
7
|
+
echo ""
|
|
8
|
+
|
|
9
|
+
# Detect project type and run appropriate tests
|
|
10
|
+
if [[ -f *.csproj ]] || find . -maxdepth 2 -name "*.csproj" 2>/dev/null | grep -q .; then
|
|
11
|
+
# .NET project detected
|
|
12
|
+
echo "๐ฆ Detected .NET project"
|
|
13
|
+
|
|
14
|
+
if ! dotnet test --verbosity minimal --no-build --no-restore 2>/dev/null; then
|
|
15
|
+
echo ""
|
|
16
|
+
echo "โ .NET tests failed!"
|
|
17
|
+
echo ""
|
|
18
|
+
echo "Fix failing tests before pushing."
|
|
19
|
+
echo "Override with: git push --no-verify"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
elif [[ -f package.json ]]; then
|
|
24
|
+
# Node.js project detected
|
|
25
|
+
echo "๐ฆ Detected Node.js project"
|
|
26
|
+
|
|
27
|
+
if ! npm test 2>/dev/null; then
|
|
28
|
+
echo ""
|
|
29
|
+
echo "โ Node.js tests failed!"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Fix failing tests before pushing."
|
|
32
|
+
echo "Override with: git push --no-verify"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
else
|
|
37
|
+
echo "โ ๏ธ No recognized test framework found"
|
|
38
|
+
echo " Skipping test execution"
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo ""
|
|
43
|
+
echo "โ
All tests passed - safe to push"
|
|
44
|
+
exit 0
|
|
@@ -84,7 +84,7 @@ export function getBuildSteps(stack, { cwd, frontendPath, backendPath } = {}) {
|
|
|
84
84
|
|
|
85
85
|
if (isFrontendStack(s)) {
|
|
86
86
|
const frontendDir = frontendPath ? join(cwd, frontendPath) : cwd;
|
|
87
|
-
// node_modules guard
|
|
87
|
+
// node_modules guard : a fresh worktree before
|
|
88
88
|
// `morph-spec worktree link` has tsconfig.json (versioned) but no toolchain โ running
|
|
89
89
|
// `npx tsc` there fetches an unrelated "tsc" package and fails noisily. No toolchain โ
|
|
90
90
|
// no tsc step; the real typecheck runs wherever node_modules exists (root/CI).
|
|
@@ -29,10 +29,8 @@ export const OUTPUT_PHASE_MAP = {
|
|
|
29
29
|
uiComponents: 'uiux',
|
|
30
30
|
uiFlows: 'uiux',
|
|
31
31
|
spec: 'plan',
|
|
32
|
-
mandate: 'plan',
|
|
33
32
|
tasks: 'plan',
|
|
34
33
|
decisions: 'plan',
|
|
35
|
-
reuseMap: 'plan',
|
|
36
34
|
usecases: 'plan',
|
|
37
35
|
recap: 'implement',
|
|
38
36
|
evidencias: 'implement',
|
|
@@ -49,10 +47,8 @@ export const FILENAME_TO_OUTPUT = {
|
|
|
49
47
|
'components.md': 'uiComponents',
|
|
50
48
|
'flows.md': 'uiFlows',
|
|
51
49
|
'spec.md': 'spec',
|
|
52
|
-
'mandate.md': 'mandate',
|
|
53
50
|
'tasks.json': 'tasks',
|
|
54
51
|
'decisions.md': 'decisions',
|
|
55
|
-
'reuse-map.md': 'reuseMap',
|
|
56
52
|
'recap.md': 'recap',
|
|
57
53
|
'review-report.md': 'reviewReport',
|
|
58
54
|
'evaluator-report.md': 'evaluatorReport',
|
|
@@ -65,7 +61,6 @@ export const PROTECTED_SPEC_FILES = {
|
|
|
65
61
|
'components.md': 'uiux',
|
|
66
62
|
'flows.md': 'uiux',
|
|
67
63
|
'spec.md': 'plan',
|
|
68
|
-
'mandate.md': 'plan',
|
|
69
64
|
'tasks.json': 'plan',
|
|
70
65
|
};
|
|
71
66
|
|
|
@@ -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
|
+
}
|