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
4 changes: 4 additions & 0 deletions dependency-cruiser.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const config = {
tsConfig: {
fileName: "tsconfig.build.json",
},
enhancedResolveOptions: {
exportsFields: ["exports"],
conditionNames: ["import", "node", "default"],
},
},
};

Expand Down
2 changes: 1 addition & 1 deletion nix/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ buildNpmPackageNode24 rec {
|| baseName == "result");
};

npmDepsHash = "sha256-22/Z3RkueF3fcG4gk8qJB7a3xr+IJvJNNFbehUrrIL4=";
npmDepsHash = "sha256-azGNdflUJ6C5gu5QQT4rQB685S9jk2ImyORrVXOncwU=";
npmDepsFetcherVersion = 2;

dontNpmBuild = true;
Expand Down
39 changes: 23 additions & 16 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"@earendil-works/pi-coding-agent": "0.84.2",
"@earendil-works/pi-tui": "0.84.2",
"pi-subagents": "0.61.0",
"superpowers": "https://github.com/obra/superpowers/archive/refs/tags/v6.3.0.tar.gz"
"superpowers": "https://github.com/obra/superpowers/archive/refs/tags/v6.3.0.tar.gz",
"typebox": "1.3.7"
}
}
5 changes: 3 additions & 2 deletions src/cli/commands/doctor/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ function parseSkillFrontmatter(
text: string,
): { name: string; description: string } | { error: string } {
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u);
if (!match) {
const frontmatter = match?.[1];
if (frontmatter === undefined) {
return { error: "missing frontmatter" };
}

Expand All @@ -224,7 +225,7 @@ function parseSkillFrontmatter(
let currentKey: string | undefined;
let currentValueAllowsContinuation = false;

for (const line of match[1].split(/\r?\n/u)) {
for (const line of frontmatter.split(/\r?\n/u)) {
const trimmed = line.trim();

if (/^[^\s].*:/u.test(line)) {
Expand Down
6 changes: 4 additions & 2 deletions src/cli/commands/doctor/pi-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
loadProjectContextFiles,
loadSkills,
SettingsManager,
type MissingSourceAction,
type ResolvedResource,
} from "@earendil-works/pi-coding-agent";
import { loadPatchmillConfigState } from "../../../config/load.ts";
Expand All @@ -26,6 +25,8 @@ import {
import { localPiAgentDir } from "../init/pi-agent-settings.ts";
import type { DoctorCheckResult } from "./checks.ts";

type MissingSourceAction = "install" | "skip" | "error";

export type DoctorPiResourceSection = {
heading: "Context" | "Skills" | "Prompts" | "Extensions";
items: string[];
Expand Down Expand Up @@ -397,7 +398,8 @@ export async function loadDoctorPiResources(
if (block.sections.length > 0) blocks.push(block);
}

return { blocks, check: piResourceWarningCheck(warnings) };
const check = piResourceWarningCheck(warnings);
return check === undefined ? { blocks } : { blocks, check };
} catch (error) {
return { blocks: [], check: piResourceDiscoveryFailureCheck(error) };
}
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/init/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function parseArgs(args: string[], repoRoot = cwd()): InitConfig {

for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === undefined) throw new Error("Unexpected missing argument");
if (arg === "--help" || arg === "-h") {
config.showHelp = true;
} else if (arg === "--yes") {
Expand Down
12 changes: 6 additions & 6 deletions src/cli/commands/init/config-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type InitialConfigSkills = Pick<

type InitialConfig = {
host: Pick<PatchmillConfig["host"], "provider" | "login">;
skills?: InitialConfigSkills;
skills?: InitialConfigSkills | undefined;
};

export type InitWriteResult =
Expand All @@ -40,9 +40,9 @@ export function inferHostProviderFromRemote(

export function buildInitialConfig(
options: {
provider?: PatchmillConfig["host"]["provider"];
login?: string;
skills?: InitialConfigSkills;
provider?: PatchmillConfig["host"]["provider"] | undefined;
login?: string | undefined;
skills?: InitialConfigSkills | undefined;
} = {},
): InitialConfig {
const provider = options.provider ?? DEFAULT_PATCHMILL_CONFIG.host.provider;
Expand Down Expand Up @@ -99,8 +99,8 @@ async function originRemoteUrl(repoRoot: string): Promise<string | undefined> {
export async function writeInitialConfig(
repoRoot: string,
options: {
login?: string;
skills?: InitialConfigSkills;
login?: string | undefined;
skills?: InitialConfigSkills | undefined;
},
): Promise<InitWriteResult> {
const path = join(repoRoot, CONFIG_FILE_NAME);
Expand Down
14 changes: 7 additions & 7 deletions src/cli/commands/init/pi-auth-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ class OptionComponent extends Container {
async function promptText(options: {
title: string;
prompt: string;
allowEmpty?: boolean;
terminal?: Terminal;
signal?: AbortSignal;
allowEmpty?: boolean | undefined;
terminal?: Terminal | undefined;
signal?: AbortSignal | undefined;
}): Promise<string | undefined> {
const terminal = options.terminal ?? new ProcessTerminal();
const tui = new TuiMainScreen(terminal, true);
Expand Down Expand Up @@ -157,7 +157,7 @@ async function promptText(options: {

export function promptApiKeyInteractively(options: {
providerName: string;
terminal?: Terminal;
terminal?: Terminal | undefined;
}): Promise<string | undefined> {
return promptText({
title: options.providerName,
Expand All @@ -169,7 +169,7 @@ export function promptApiKeyInteractively(options: {
async function selectOption(options: {
title: string;
choices: Array<{ id: string; label: string }>;
terminal?: Terminal;
terminal?: Terminal | undefined;
}): Promise<string | undefined> {
const terminal = options.terminal ?? new ProcessTerminal();
const tui = new TuiMainScreen(terminal, false);
Expand Down Expand Up @@ -213,8 +213,8 @@ function defaultOpenUrl(url: string): void {

export function createOAuthCallbacks(
options: {
terminal?: Terminal;
openUrl?: OpenUrl;
terminal?: Terminal | undefined;
openUrl?: OpenUrl | undefined;
} = {},
): OAuthLoginCallbacksLike {
const terminal = options.terminal ?? new ProcessTerminal();
Expand Down
35 changes: 19 additions & 16 deletions src/cli/commands/init/pi-auth-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,25 @@ import {
} from "./pi-runtime.ts";

export type OAuthLoginCallbacksLike = {
onAuth: (info: { url: string; instructions?: string }) => void;
onAuth: (info: { url: string; instructions?: string | undefined }) => void;
onDeviceCode: (info: {
userCode: string;
verificationUri: string;
intervalSeconds?: number;
expiresInSeconds?: number;
intervalSeconds?: number | undefined;
expiresInSeconds?: number | undefined;
}) => void;
onPrompt: (prompt: {
message: string;
placeholder?: string;
allowEmpty?: boolean;
placeholder?: string | undefined;
allowEmpty?: boolean | undefined;
}) => Promise<string>;
onProgress?: (message: string) => void;
onManualCodeInput?: () => Promise<string>;
onSelect: (prompt: {
message: string;
options: Array<{ id: string; label: string }>;
}) => Promise<string | undefined>;
signal?: AbortSignal;
signal?: AbortSignal | undefined;
dispose?: () => void;
};

Expand All @@ -75,8 +75,8 @@ type SelectAuthPromptOption = (prompt: {

type PromptAuthText = (prompt: {
message: string;
placeholder?: string;
allowEmpty?: boolean;
placeholder?: string | undefined;
allowEmpty?: boolean | undefined;
}) => Promise<string | undefined>;

export type InteractivePiAuthSetupOptions = {
Expand All @@ -89,8 +89,8 @@ export type InteractivePiAuthSetupOptions = {
selectProvider: SelectAuthProvider;
promptApiKey: PromptApiKey;
selectModelInteractively: SelectInteractiveModel;
persistDefaultModel?: PersistDefaultModel;
oauthCallbacks?: OAuthCallbacksFactory;
persistDefaultModel?: PersistDefaultModel | undefined;
oauthCallbacks?: OAuthCallbacksFactory | undefined;
};

type InteractivePiAuthSetupResult = {
Expand Down Expand Up @@ -128,7 +128,7 @@ async function promptForAuthValue(options: {
prompt: PiAuthPrompt;
provider: AuthProviderChoice;
promptApiKey: PromptApiKey;
promptText?: PromptAuthText;
promptText?: PromptAuthText | undefined;
selectOption: SelectAuthPromptOption;
}): Promise<string> {
if (options.prompt.type === "select") {
Expand Down Expand Up @@ -174,7 +174,7 @@ async function promptForAuthValue(options: {
function createApiKeyInteraction(options: {
provider: AuthProviderChoice;
promptApiKey: PromptApiKey;
promptText?: PromptAuthText;
promptText?: PromptAuthText | undefined;
selectOption: SelectAuthPromptOption;
}): PiAuthInteraction {
return {
Expand All @@ -194,10 +194,13 @@ function createPiAuthInteraction(
callbacks: OAuthLoginCallbacksLike,
): PiAuthInteraction {
return {
signal: callbacks.signal,
...(callbacks.signal === undefined ? {} : { signal: callbacks.signal }),
notify: (event: PiAuthEvent) => {
if (event.type === "auth_url") {
callbacks.onAuth({ url: event.url, instructions: event.instructions });
callbacks.onAuth({
url: event.url,
instructions: event.instructions,
});
} else if (event.type === "device_code") {
callbacks.onDeviceCode({
userCode: event.userCode,
Expand Down Expand Up @@ -336,8 +339,8 @@ export async function setupPiInteractively(options: {
agentDir: string;
currentDefault: LocalPiDefaultModel | undefined;
initialReadiness: PiReadiness;
selectModelInteractively?: SelectInteractiveModel;
persistDefaultModel?: PersistDefaultModel;
selectModelInteractively?: SelectInteractiveModel | undefined;
persistDefaultModel?: PersistDefaultModel | undefined;
}): Promise<InteractivePiAuthSetupResult> {
const { runtime } = await createRepoLocalPiAuth({
agentDir: options.agentDir,
Expand Down
Loading
Loading