From 8060a3935235f78293660b7b545150148f94c142 Mon Sep 17 00:00:00 2001 From: alpertarhan Date: Mon, 7 Sep 2026 14:56:56 +0300 Subject: [PATCH 1/2] fix: explain expected reference formats in ref validation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'invalid Forgejo reference' gave the model no way to recover: the ref parameter is a resource reference (server:owner/repo#N / !N / bare repo / fj://...), but agents naturally pass git tags or branches there — especially for forgejo_actions, where filtering runs by a tag is a legitimate intent with its own git_ref parameter. The retry loop that follows wastes turns and tokens. All three validation sites (ForgejoRuntime.resolveRepo, resolveResource, and the /fj command path) now append the accepted formats and point git tags/branches at git_ref, so a single error is enough to self-correct. Observed in a live session: gpt-5.6-sol passed 'v0.21.13-pilot' as ref and spiraled on repeated opaque rejections; with the hint the same request completes on the next try. --- src/extension.ts | 2 +- src/runtime.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 7e7a527..c3bd0b0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -396,7 +396,7 @@ export default function forgejoExtension(pi: ExtensionAPI): void { const value = args.trim(); if (value) { const ref = parseResourceRef(value); - if (!ref) throw new Error(`invalid Forgejo reference '${value}'`); + if (!ref) throw new Error(`invalid Forgejo reference '${value}' — expected 'server:owner/repo#N' (issue), 'server:owner/repo!N' (pull), 'server:owner/repo' (repo), or 'fj://server/owner/repo//'; for git tags/branches use the git_ref parameter`); const server = current.config.servers[ref.server]; if (!server) throw new Error(`unknown server '${ref.server}'`); await openExternal(pi, resourceWebUrl(ref, server), server.baseUrl); diff --git a/src/runtime.ts b/src/runtime.ts index 214e940..3b6bb73 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -15,6 +15,9 @@ import type { ReviewDraft, } from "./types.js"; +const REF_FORMAT_HINT = + "expected 'server:owner/repo#N' (issue), 'server:owner/repo!N' (pull), 'server:owner/repo' (repo), or 'fj://server/owner/repo//'; for git tags/branches use the git_ref parameter"; + export interface RepoInput { ref?: string; server?: string; @@ -102,7 +105,7 @@ export class ForgejoRuntime { if (input.ref) { const resource = parseResourceRef(input.ref); if (!resource) - throw new Error(`invalid Forgejo reference '${input.ref}'`); + throw new Error(`invalid Forgejo reference '${input.ref}' — ${REF_FORMAT_HINT}`); this.clients.get(resource.server); return { server: resource.server, @@ -139,7 +142,7 @@ export class ForgejoRuntime { if (input.ref) { const resource = parseResourceRef(input.ref); if (!resource) - throw new Error(`invalid Forgejo reference '${input.ref}'`); + throw new Error(`invalid Forgejo reference '${input.ref}' — ${REF_FORMAT_HINT}`); if (resource.kind !== kind) throw new Error(`reference '${input.ref}' is not a ${kind}`); this.clients.get(resource.server); From b263a005eb864898c7258c4e8ed7c9de07ab9853 Mon Sep 17 00:00:00 2001 From: alpertarhan Date: Mon, 7 Sep 2026 14:57:06 +0300 Subject: [PATCH 2/2] feat: declare explicit pi entry and omp extension manifest Pin the pi entry to the extension file instead of the directory, and declare the same entry under omp so the oh-my-pi fork's native package discovery picks the toolkit up without the legacy path. pi behavior is unchanged (same module, explicit path); omp loads it from its own registry entry. --- package.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ff4cbc4..7256a4d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,12 @@ }, "pi": { "extensions": [ - "./extensions" + "./extensions/forgejo/index.ts" + ] + }, + "omp": { + "extensions": [ + "./extensions/forgejo/index.ts" ] }, "peerDependencies": {