Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

### Changed

- The dashboard widget and its footer status are now off by default (`dashboard.enabled: false`): a repository still activates the tools and skills, but nothing is drawn on screen until the dashboard is enabled explicitly. Watch notifications keep following `dashboard.notifications` independently.
- Host-adaptive config locations: under omp the active agent directory (`~/.omp/agent`) and project `.omp/` directory are preferred, with a legacy fallback so an existing `~/.pi/agent/forgejo.json` or `<cwd>/.pi/forgejo.json` keeps working unchanged; pi paths are untouched.

## [0.9.0] - 2026-09-07

### Added
Expand Down
53 changes: 48 additions & 5 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { existsSync } from "node:fs";
import { readFile } from "node:fs/promises";
import { homedir } from "node:os";
import { dirname, isAbsolute, resolve } from "node:path";
Expand All @@ -18,7 +19,7 @@ import type {
} from "./types.js";

const DEFAULT_DASHBOARD: DashboardConfig = {
enabled: true,
enabled: false,
scope: "all",
refreshSeconds: 90,
previewLimit: 3,
Expand Down Expand Up @@ -398,16 +399,58 @@ export async function loadGlobalAllowedMutations(
throw new ConfigError(`${globalConfigPath} must contain a JSON object`);
return parseAllowedMutationKeys(value.allowedMutations);
}
interface ConfigHostContext {
isOmp: boolean;
agentDir?: string | undefined;
}

let hostContext: ConfigHostContext | undefined;

/**
* Called by the extension entry once the host module is available. Keeps
* config.ts free of pi-coding-agent imports (which would drag optional
* dependencies into the test graph) while letting the running host decide
* where config lives.
*/
export function setConfigHostContext(context: ConfigHostContext | undefined): void {
hostContext = context;
}

/**
* Host-adaptive config locations with a legacy fallback.
*
* pi keeps its historical paths (~/.pi/agent/forgejo.json, <cwd>/.pi/).
* Under omp the active agent directory is ~/.omp/agent and the project
* config directory is .omp/, but a config left at the legacy .pi location
* keeps working so existing shared setups do not break on upgrade.
*/
export function configPaths(
cwd: string,
env: NodeJS.ProcessEnv = process.env,
): { global: string; project: string } {
const legacyGlobal = resolve(homedir(), ".pi", "agent", "forgejo.json");
let global = legacyGlobal;
let project = resolve(cwd, ".pi", "forgejo.json");
if (hostContext?.isOmp) {
const hostGlobal = hostContext.agentDir
? resolve(hostContext.agentDir, "forgejo.json")
: legacyGlobal;
const hostProject = resolve(cwd, ".omp", "forgejo.json");
const legacyProject = resolve(cwd, ".pi", "forgejo.json");
global = existsSync(hostGlobal)
? hostGlobal
: existsSync(legacyGlobal)
? legacyGlobal
: hostGlobal;
project = existsSync(hostProject)
? hostProject
: existsSync(legacyProject)
? legacyProject
: hostProject;
}
return {
global: env.PI_FORGEJO_CONFIG
? resolve(env.PI_FORGEJO_CONFIG)
: resolve(homedir(), ".pi", "agent", "forgejo.json"),
project: resolve(cwd, ".pi", "forgejo.json"),
global: env.PI_FORGEJO_CONFIG ? resolve(env.PI_FORGEJO_CONFIG) : global,
project,
};
}

Expand Down
20 changes: 20 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { homedir } from "node:os";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
import type {
ExtensionAPI,
ExtensionContext,
} from "@earendil-works/pi-coding-agent";
import type { AutocompleteProvider } from "@earendil-works/pi-tui";
import { setConfigHostContext } from "./config.js";
import { runForgejoSetup, type SetupStage } from "./setup.js";
import { createForgejoAutocompleteProvider } from "./dashboard/autocomplete.js";
import { DashboardNotifier } from "./dashboard/notifier.js";
Expand Down Expand Up @@ -462,6 +465,23 @@ export default function forgejoExtension(pi: ExtensionAPI): void {
});

pi.on("session_start", async (_event, ctx) => {
// Host-adaptive config location: pi sets PI_CODING_AGENT=true for
// extensions, omp does not. Resolved from the environment (never a
// pi-coding-agent import, which would pull optional dependencies into
// build graphs). PI_CODING_AGENT_DIR relocates the agent dir on both
// hosts; omp profiles live under ~/.omp/profiles/<name>/agent.
const isPi = process.env.PI_CODING_AGENT === "true";
const profile = process.env.OMP_PROFILE?.trim();
setConfigHostContext({
isOmp: !isPi,
agentDir:
process.env.PI_CODING_AGENT_DIR?.trim() ||
(isPi
? resolve(homedir(), ".pi", "agent")
: profile
? resolve(homedir(), ".omp", "profiles", profile, "agent")
: resolve(homedir(), ".omp", "agent")),
});
forgejoTools.reset();
forgejoActive = false;
cleanup();
Expand Down
2 changes: 1 addition & 1 deletion test/config-refs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe("Forgejo configuration", () => {
remoteHosts: ["forgejo.work.example", "forgejo-work"],
});
expect(config.dashboard).toEqual({
enabled: true,
enabled: false,
scope: "all",
refreshSeconds: 90,
previewLimit: 3,
Expand Down