diff --git a/packages/coding-agent/src/cli.ts b/packages/coding-agent/src/cli.ts index f434e65..f14206f 100644 --- a/packages/coding-agent/src/cli.ts +++ b/packages/coding-agent/src/cli.ts @@ -7,9 +7,9 @@ */ process.title = "pi"; +import { bedrockProviderModule } from "@mariozechner/pi-ai/bedrock-provider"; import { setBedrockProviderModule } from "@mariozechner/pi-ai"; import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici"; -import { bedrockProviderModule } from "../../ai/src/bedrock-provider.js"; import { main } from "./main.js"; setGlobalDispatcher(new EnvHttpProxyAgent()); diff --git a/packages/pi-grind/package.json b/packages/pi-grind/package.json index 70ded13..2645465 100644 --- a/packages/pi-grind/package.json +++ b/packages/pi-grind/package.json @@ -7,7 +7,7 @@ "pi-package" ], "license": "MIT", - "author": "OpenAI", + "author": "Mario Zechner", "main": "./src/index.ts", "files": [ "src", diff --git a/packages/pi-grind/src/state.ts b/packages/pi-grind/src/state.ts index 88ccb13..5173ad4 100644 --- a/packages/pi-grind/src/state.ts +++ b/packages/pi-grind/src/state.ts @@ -52,7 +52,6 @@ export function createRunState(input: { lastNextAction: null, pendingRepair: false, consecutiveParseFailures: 0, - consecutiveControllerFailures: 0, updatedAt: now, }; } @@ -75,7 +74,6 @@ export function isValidRunState(value: unknown): value is GrindRunState { isNullableString(value.lastNextAction) && typeof value.pendingRepair === "boolean" && typeof value.consecutiveParseFailures === "number" && - typeof value.consecutiveControllerFailures === "number" && typeof value.updatedAt === "string" ); } @@ -114,19 +112,6 @@ export function withLoopStatus(state: GrindRunState, payload: GrindStatusPayload lastNextAction: payload.nextAction ?? null, pendingRepair: false, consecutiveParseFailures: 0, - consecutiveControllerFailures: 0, - updatedAt: new Date().toISOString(), - }; -} - -export function withControllerFailure(state: GrindRunState, note: string): GrindRunState { - return { - ...state, - status: "blocked", - lastCheckpoint: note, - lastNextAction: null, - pendingRepair: false, - consecutiveControllerFailures: state.consecutiveControllerFailures + 1, updatedAt: new Date().toISOString(), }; } diff --git a/packages/pi-grind/src/time.ts b/packages/pi-grind/src/time.ts index b1cc295..5f4dbdc 100644 --- a/packages/pi-grind/src/time.ts +++ b/packages/pi-grind/src/time.ts @@ -47,6 +47,27 @@ function stripTrailingContinuation(text: string): string { .trim(); } +function parseLocalDateOnly(candidate: string): Date | null { + const match = candidate.match(/^(\d{4})-(\d{2})-(\d{2})$/); + if (!match) { + return null; + } + + const year = Number(match[1]); + const month = Number(match[2]); + const day = Number(match[3]); + const local = new Date(year, month - 1, day, 0, 0, 0, 0); + if ( + local.getFullYear() !== year || + local.getMonth() !== month - 1 || + local.getDate() !== day + ) { + return null; + } + + return local; +} + export function parseDeadline(raw: string, now: Date = new Date()): Date | null { const candidate = raw.trim(); if (!candidate) { @@ -85,6 +106,10 @@ export function parseDeadline(raw: string, now: Date = new Date()): Date | null const time = parseClockValue(stripTrailingContinuation(normalized)); if (!time) { + const localDateOnly = parseLocalDateOnly(candidate); + if (localDateOnly) { + return localDateOnly; + } const direct = new Date(candidate); if (!Number.isNaN(direct.getTime())) { return direct; diff --git a/packages/pi-grind/src/types.ts b/packages/pi-grind/src/types.ts index d58a5c4..4f1dfc9 100644 --- a/packages/pi-grind/src/types.ts +++ b/packages/pi-grind/src/types.ts @@ -25,7 +25,7 @@ export interface ParsedStopCondition { } export interface ParsedAutoActivation { - matchedCue: string | null; + matchedCue: string; stopCondition: ParsedStopCondition; } @@ -48,6 +48,5 @@ export interface GrindRunState { lastNextAction: string | null; pendingRepair: boolean; consecutiveParseFailures: number; - consecutiveControllerFailures: number; updatedAt: string; } diff --git a/packages/pi-grind/test/parser.test.ts b/packages/pi-grind/test/parser.test.ts index cfa01f4..a4dee7d 100644 --- a/packages/pi-grind/test/parser.test.ts +++ b/packages/pi-grind/test/parser.test.ts @@ -30,6 +30,13 @@ describe("pi-grind parser", () => { expect(result?.stopCondition.deadlineAt).toBe(new Date(2026, 2, 10, 17, 30, 0).toISOString()); }); + it("parses bare ISO dates in local time instead of UTC midnight", () => { + const result = parseStopCondition("keep going until 2026-03-10", now); + + expect(result.deadlineAt).toBe(new Date(2026, 2, 10, 0, 0, 0).toISOString()); + expect(result.completionCriterion).toBeNull(); + }); + it("parses grind status trailers", () => { const payload = parseGrindStatus( 'Work done.\n{"state":"continue","summary":"half done","nextAction":"finish tests"}', diff --git a/tsconfig.json b/tsconfig.json index 998038c..1e6f32b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,9 @@ "paths": { "*": ["./*"], "@mariozechner/pi-ai": ["./packages/ai/src/index.ts"], + "@mariozechner/pi-ai/bedrock-provider": [ + "./packages/ai/src/bedrock-provider.ts" + ], "@mariozechner/pi-ai/oauth": ["./packages/ai/src/oauth.ts"], "@mariozechner/pi-ai/*": ["./packages/ai/src/*"], "@mariozechner/pi-ai/dist/*": ["./packages/ai/src/*"],