From 4e56b46dc9d8e893b25f7821e137ffe75f05ed34 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Tue, 11 Aug 2026 12:26:00 -0400 Subject: [PATCH] fix: missing sawMessage init in accumulator literal; add pre-commit port typecheck hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI port job's tsc --noEmit caught SessionEventAccumulator literals not initializing the new sawMessage field (tests don't typecheck, so bun test was green). Add a committed .githooks/pre-commit that mirrors the CI port job — regenerate the port into a temp dir and tsc --noEmit it — so this class of error fails at commit time, not in CI. --- .githooks/pre-commit | 37 +++++++++++++++++++++++++++++++++++++ README.md | 15 +++++++++++++++ src/agent-runner.ts | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..2b1f36a --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,37 @@ +#!/bin/sh +# pre-commit — typecheck the generated omp port before committing. +# +# Mirrors the CI port job (.gitea/workflows/port-to-omp.yml). The source +# repo's own tsconfig extends the host harness tsconfig and is not +# self-contained, so the reliable typecheck target is the regenerated port: +# it ships a self-contained tsconfig and the pinned @oh-my-pi SDK as a real +# devDependency. Regenerating into a temp dir and running `tsc --noEmit` +# there catches exactly what CI will fail on (e.g. an interface field added +# without updating its object literals). +# +# Enable (per clone): git config core.hooksPath .githooks +set -euo pipefail + +ROOT="$(git rev-parse --show-toplevel)" +cd "$ROOT" + +# Fast path: no TypeScript-adjacent change staged -> nothing to typecheck. +if git diff --cached --quiet -- src/ agents/ package.json tsconfig.json port-to-omp.mjs; then + exit 0 +fi + +TMP="$(mktemp -d)" +LOG="$(mktemp)" +trap 'rm -rf "$TMP" "$LOG"' EXIT + +if ! bun port-to-omp.mjs --out "$TMP" >"$LOG" 2>&1; then + echo "pre-commit: port regeneration failed (CI would fail too) — output:" >&2 + tail -20 "$LOG" >&2 + exit 1 +fi + +if ! (cd "$TMP" && bun run typecheck) >"$LOG" 2>&1; then + echo "pre-commit: port typecheck failed (this is what CI runs) — output:" >&2 + tail -30 "$LOG" >&2 + exit 1 +fi diff --git a/README.md b/README.md index 47e7c91..5b29e9d 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,21 @@ pygienium/ └─ agents/ ← scanner.md fixer.md deep-modules.md defensive-guards.md ``` +## Development + +The omp port at `~/.omp/agent/extensions/pygienium` is regenerated **only by CI +on push** (`.gitea/workflows/port-to-omp.yml`) — never by hand. + +The source repo's own `tsconfig.json` extends the host harness tsconfig, so the +reliable typecheck target is the regenerated port (self-contained tsconfig + +pinned `@oh-my-pi` SDK devDependency). A committed pre-commit hook runs exactly +what CI runs — regenerate the port into a temp dir and `tsc --noEmit` it — and +fails the commit on any error: + +```sh +git config core.hooksPath .githooks +``` + ## License MIT diff --git a/src/agent-runner.ts b/src/agent-runner.ts index c20eb88..d3d5ca4 100644 --- a/src/agent-runner.ts +++ b/src/agent-runner.ts @@ -243,7 +243,7 @@ async function runSessionToCompletion( session: AgentSession, opts: AgentTaskOptions, ): Promise { - const acc: SessionEventAccumulator = { text: "" }; + const acc: SessionEventAccumulator = { text: "", sawMessage: false }; try { const unsubscribe = session.subscribe((event: AgentSessionEvent) => { applySessionEvent(acc, event, opts.onEvent);