fix(coding-agent): remove process-cwd tool singletons and use tool-name allowlists
- switch SDK/CLI tool selection to name-based allowlists - apply allowlists across built-in, extension, and SDK tools - remove ambient process.cwd defaults from core tooling and resource helpers - update tests, examples, and TUI callers for explicit cwd plumbing - add regression coverage for extension tool filtering closes #3452 closes #2835
This commit is contained in:
@@ -20,31 +20,49 @@ import type { ExtensionAPI, ExtensionContext, WorkingIndicatorOptions } from "@m
|
||||
|
||||
type WorkingIndicatorMode = "dot" | "none" | "pulse" | "spinner" | "default";
|
||||
|
||||
const SPINNER_INDICATOR: WorkingIndicatorOptions = {
|
||||
frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
||||
intervalMs: 80,
|
||||
};
|
||||
const DOT_INDICATOR: WorkingIndicatorOptions = {
|
||||
frames: ["●"],
|
||||
};
|
||||
const PULSE_INDICATOR: WorkingIndicatorOptions = {
|
||||
frames: ["·", "•", "●", "•"],
|
||||
intervalMs: 120,
|
||||
};
|
||||
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
||||
const PASTEL_RAINBOW = [
|
||||
"\x1b[38;2;255;179;186m",
|
||||
"\x1b[38;2;255;223;186m",
|
||||
"\x1b[38;2;255;255;186m",
|
||||
"\x1b[38;2;186;255;201m",
|
||||
"\x1b[38;2;186;225;255m",
|
||||
"\x1b[38;2;218;186;255m",
|
||||
];
|
||||
const RESET_FG = "\x1b[39m";
|
||||
const HIDDEN_INDICATOR: WorkingIndicatorOptions = {
|
||||
frames: [],
|
||||
};
|
||||
|
||||
function colorize(text: string, color: string): string {
|
||||
return `${color}${text}${RESET_FG}`;
|
||||
}
|
||||
|
||||
function getIndicator(mode: WorkingIndicatorMode): WorkingIndicatorOptions | undefined {
|
||||
switch (mode) {
|
||||
case "dot":
|
||||
return DOT_INDICATOR;
|
||||
return {
|
||||
frames: [colorize("●", PASTEL_RAINBOW[0])],
|
||||
};
|
||||
case "none":
|
||||
return HIDDEN_INDICATOR;
|
||||
case "pulse":
|
||||
return PULSE_INDICATOR;
|
||||
return {
|
||||
frames: [
|
||||
colorize("·", PASTEL_RAINBOW[0]),
|
||||
colorize("•", PASTEL_RAINBOW[2]),
|
||||
colorize("●", PASTEL_RAINBOW[4]),
|
||||
colorize("•", PASTEL_RAINBOW[5]),
|
||||
],
|
||||
intervalMs: 120,
|
||||
};
|
||||
case "spinner":
|
||||
return SPINNER_INDICATOR;
|
||||
return {
|
||||
frames: SPINNER_FRAMES.map((frame, index) =>
|
||||
colorize(frame, PASTEL_RAINBOW[index % PASTEL_RAINBOW.length]!),
|
||||
),
|
||||
intervalMs: 80,
|
||||
};
|
||||
case "default":
|
||||
return undefined;
|
||||
}
|
||||
@@ -66,7 +84,7 @@ function describeMode(mode: WorkingIndicatorMode): string {
|
||||
}
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
let mode: WorkingIndicatorMode = "dot";
|
||||
let mode: WorkingIndicatorMode = "spinner";
|
||||
|
||||
const applyIndicator = (ctx: ExtensionContext) => {
|
||||
ctx.ui.setWorkingIndicator(getIndicator(mode));
|
||||
|
||||
@@ -4,10 +4,15 @@
|
||||
* Shows how to replace or modify the default system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const cwd = process.cwd();
|
||||
const agentDir = getAgentDir();
|
||||
|
||||
// Option 1: Replace prompt entirely
|
||||
const loader1 = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
systemPromptOverride: () => `You are a helpful assistant that speaks like a pirate.
|
||||
Always end responses with "Arrr!"`,
|
||||
// Needed to avoid DefaultResourceLoader appending APPEND_SYSTEM.md from ~/.pi/agent or <cwd>/.pi.
|
||||
@@ -32,6 +37,8 @@ console.log("\n");
|
||||
|
||||
// Option 2: Append instructions to the default prompt
|
||||
const loader2 = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
appendSystemPromptOverride: (base) => [
|
||||
...base,
|
||||
"## Additional Instructions\n- Always be concise\n- Use bullet points when listing things",
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
createAgentSession,
|
||||
createSyntheticSourceInfo,
|
||||
DefaultResourceLoader,
|
||||
getAgentDir,
|
||||
SessionManager,
|
||||
type Skill,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
@@ -24,6 +25,8 @@ const customSkill: Skill = {
|
||||
};
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd: process.cwd(),
|
||||
agentDir: getAgentDir(),
|
||||
skillsOverride: (current) => {
|
||||
const filteredSkills = current.skills.filter((s) => s.name.includes("browser") || s.name.includes("search"));
|
||||
return {
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
* export default function (pi: ExtensionAPI) { ... }
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Extensions are discovered automatically from standard locations.
|
||||
// You can also add paths via settings.json or DefaultResourceLoader options.
|
||||
|
||||
const resourceLoader = new DefaultResourceLoader({
|
||||
cwd: process.cwd(),
|
||||
agentDir: getAgentDir(),
|
||||
additionalExtensionPaths: ["./my-logging-extension.ts", "./my-safety-extension.ts"],
|
||||
extensionFactories: [
|
||||
(pi) => {
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
* Context files provide project-specific instructions loaded into the system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Disable context files entirely by returning an empty list in agentsFilesOverride.
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd: process.cwd(),
|
||||
agentDir: getAgentDir(),
|
||||
agentsFilesOverride: (current) => ({
|
||||
agentsFiles: [
|
||||
...current.agentsFiles,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
createAgentSession,
|
||||
createSyntheticSourceInfo,
|
||||
DefaultResourceLoader,
|
||||
getAgentDir,
|
||||
type PromptTemplate,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
@@ -26,6 +27,8 @@ const deployTemplate: PromptTemplate = {
|
||||
};
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd: process.cwd(),
|
||||
agentDir: getAgentDir(),
|
||||
promptsOverride: (current) => ({
|
||||
prompts: [...current.prompts, deployTemplate],
|
||||
diagnostics: current.diagnostics,
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
|
||||
import { createAgentSession, SessionManager, SettingsManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
// Load current settings (merged global + project)
|
||||
const settingsManagerFromDisk = SettingsManager.create();
|
||||
const settingsManagerFromDisk = SettingsManager.create(cwd);
|
||||
console.log("Current settings:", JSON.stringify(settingsManagerFromDisk.getGlobalSettings(), null, 2));
|
||||
|
||||
// Override specific settings
|
||||
const settingsManager = SettingsManager.create();
|
||||
const settingsManager = SettingsManager.create(cwd);
|
||||
settingsManager.applyOverrides({
|
||||
compaction: { enabled: false },
|
||||
retry: { enabled: true, maxRetries: 5, baseDelayMs: 1000 },
|
||||
|
||||
Reference in New Issue
Block a user