Merge remote-tracking branch 'public-gh/master'

* public-gh/master:
  Address PR feedback: keep testEnvironment non-destructive, warn on swallowed errors
  Apply suggestion from @greptile-apps[bot]
  Fix opencode-local adapter: parser, UI, CLI, and environment tests
  Rename Invoke button to Run Heartbeat for clarity
  fixing overhanging recommended text in onboarding
  Add Contributing guide
  feat(pi-local): fix bugs, add RPC mode, improve cost tracking and output handling
  fix(sidebar-badges): include approvals in inbox badge count
  feat: add Pi adapter support to constants and onboarding UI
  Adding support for pi-local
  ci: clarify fail-fast lockfile refresh behavior
  ci: remove unnecessary full-history checkout
  ci: fix pnpm lockfile policy checks
  ci: split workflows and move pnpm lockfile ownership to GitHub Actions
  Add License
  fix: use root option in sendFile to avoid dotfile 500 on SPA refresh

# Conflicts:
#	cli/src/adapters/registry.ts
#	pnpm-lock.yaml
#	server/src/adapters/registry.ts
#	ui/package.json
#	ui/src/adapters/registry.ts
This commit is contained in:
Dotta
2026-03-07 15:18:02 -06:00
44 changed files with 2350 additions and 995 deletions

View File

@@ -0,0 +1,47 @@
import type { AdapterConfigFieldsProps } from "../types";
import {
Field,
DraftInput,
} from "../../components/agent-config-primitives";
import { ChoosePathButton } from "../../components/PathInstructionsModal";
const inputClass =
"w-full rounded-md border border-border px-2.5 py-1.5 bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/40";
const instructionsFileHint =
"Absolute path to a markdown file (e.g. AGENTS.md) that defines this agent's behavior. Injected into the system prompt at runtime.";
export function PiLocalConfigFields({
isCreate,
values,
set,
config,
eff,
mark,
}: AdapterConfigFieldsProps) {
return (
<Field label="Agent instructions file" hint={instructionsFileHint}>
<div className="flex items-center gap-2">
<DraftInput
value={
isCreate
? values!.instructionsFilePath ?? ""
: eff(
"adapterConfig",
"instructionsFilePath",
String(config.instructionsFilePath ?? ""),
)
}
onCommit={(v) =>
isCreate
? set!({ instructionsFilePath: v })
: mark("adapterConfig", "instructionsFilePath", v || undefined)
}
immediate
className={inputClass}
placeholder="/absolute/path/to/AGENTS.md"
/>
<ChoosePathButton />
</div>
</Field>
);
}

View File

@@ -0,0 +1,12 @@
import type { UIAdapterModule } from "../types";
import { parsePiStdoutLine } from "@paperclipai/adapter-pi-local/ui";
import { PiLocalConfigFields } from "./config-fields";
import { buildPiLocalConfig } from "@paperclipai/adapter-pi-local/ui";
export const piLocalUIAdapter: UIAdapterModule = {
type: "pi_local",
label: "Pi (local)",
parseStdoutLine: parsePiStdoutLine,
ConfigFields: PiLocalConfigFields,
buildAdapterConfig: buildPiLocalConfig,
};

View File

@@ -3,6 +3,7 @@ import { claudeLocalUIAdapter } from "./claude-local";
import { codexLocalUIAdapter } from "./codex-local";
import { cursorLocalUIAdapter } from "./cursor";
import { openCodeLocalUIAdapter } from "./opencode-local";
import { piLocalUIAdapter } from "./pi-local";
import { openClawUIAdapter } from "./openclaw";
import { openClawGatewayUIAdapter } from "./openclaw-gateway";
import { processUIAdapter } from "./process";
@@ -13,6 +14,7 @@ const adaptersByType = new Map<string, UIAdapterModule>(
claudeLocalUIAdapter,
codexLocalUIAdapter,
openCodeLocalUIAdapter,
piLocalUIAdapter,
cursorLocalUIAdapter,
openClawUIAdapter,
openClawGatewayUIAdapter,