my-pi 0.1.35 → 0.1.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -7
- package/dist/api.d.ts +20 -8
- package/dist/api.js +11 -15
- package/dist/api.js.map +1 -1
- package/dist/{builtin-registry-BM3CCt86.js → builtin-registry-1hIf07ru.js} +19 -6
- package/dist/builtin-registry-1hIf07ru.js.map +1 -0
- package/dist/{hooks-resolution-D7CSDzFs.js → hooks-resolution-D89Ewkyw.js} +47 -8
- package/dist/hooks-resolution-D89Ewkyw.js.map +1 -0
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/{prompt-presets-BAXHRyX0.js → prompt-presets-Cl3vBbc-.js} +4 -4
- package/dist/prompt-presets-Cl3vBbc-.js.map +1 -0
- package/dist/{session-name-C3y6uB0x.js → session-name-8BLMnCqq.js} +3 -3
- package/dist/session-name-8BLMnCqq.js.map +1 -0
- package/dist/{startup-screen-DFywkmul.js → startup-screen-ofHxGDsk.js} +2 -2
- package/dist/startup-screen-ofHxGDsk.js.map +1 -0
- package/package.json +22 -21
- package/dist/builtin-registry-BM3CCt86.js.map +0 -1
- package/dist/hooks-resolution-D7CSDzFs.js.map +0 -1
- package/dist/prompt-presets-BAXHRyX0.js.map +0 -1
- package/dist/session-name-C3y6uB0x.js.map +0 -1
- package/dist/startup-screen-DFywkmul.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Composable [pi](https://pi.dev) coding agent for humans and agents.
|
|
9
9
|
|
|
10
10
|
Built on the
|
|
11
|
-
[@
|
|
11
|
+
[@earendil-works/pi-coding-agent](https://github.com/badlogic/pi-mono)
|
|
12
12
|
SDK. Adds MCP server support, extension stacking, LSP tools, prompt
|
|
13
13
|
presets, local SQLite telemetry for evals, and a programmatic API.
|
|
14
14
|
|
|
@@ -519,12 +519,15 @@ restore, save, and load reusable MCP server sets.
|
|
|
519
519
|
### Hooks
|
|
520
520
|
|
|
521
521
|
Claude-style hooks are discovered from `.claude/settings.json`,
|
|
522
|
-
`.rulesync/hooks.json`, and `.pi/hooks.json`.
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
522
|
+
`.rulesync/hooks.json`, and `.pi/hooks.json`. `PreToolUse` hooks run
|
|
523
|
+
before a tool executes and can block by exiting with code `2` or by
|
|
524
|
+
printing JSON like `{ "decision": "block", "reason": "..." }`.
|
|
525
|
+
`PostToolUse` and `PostToolUseFailure` hooks run after tool execution.
|
|
526
|
+
Because hook commands run through `bash -lc`, project hook config is
|
|
527
|
+
untrusted by default. Interactive sessions show the hook source files
|
|
528
|
+
and commands before allowing execution; headless sessions skip hooks
|
|
529
|
+
unless `MY_PI_HOOKS_CONFIG=allow` or `MY_PI_HOOKS_CONFIG=trust` is
|
|
530
|
+
set. Trusted hook approvals are remembered per project directory and
|
|
528
531
|
hook-config hash.
|
|
529
532
|
|
|
530
533
|
Hook commands receive a restricted child-process environment by
|
|
@@ -752,6 +755,7 @@ pi install npm:@spences10/pi-recall
|
|
|
752
755
|
pi install npm:@spences10/pi-nopeek
|
|
753
756
|
pi install npm:@spences10/pi-omnisearch
|
|
754
757
|
pi install npm:@spences10/pi-sqlite-tools
|
|
758
|
+
pi install npm:@spences10/pi-svelte-guardrails
|
|
755
759
|
pi install npm:@spences10/pi-team-mode
|
|
756
760
|
pi install npm:@spences10/pi-themes
|
|
757
761
|
```
|
|
@@ -779,6 +783,9 @@ pi install npm:@spences10/pi-themes
|
|
|
779
783
|
mcp-omnisearch reminder for verified web research
|
|
780
784
|
- [`@spences10/pi-sqlite-tools`](./packages/pi-sqlite-tools/README.md)
|
|
781
785
|
— mcp-sqlite-tools reminder for safer SQLite database work
|
|
786
|
+
- [`@spences10/pi-svelte-guardrails`](./packages/pi-svelte-guardrails/README.md)
|
|
787
|
+
— Svelte pattern guardrails that block discouraged writes like
|
|
788
|
+
`$effect`
|
|
782
789
|
- [`@spences10/pi-team-mode`](./packages/pi-team-mode/README.md) —
|
|
783
790
|
local orchestrator/team mode with RPC teammates, tasks, and
|
|
784
791
|
mailboxes
|
|
@@ -819,6 +826,7 @@ packages/
|
|
|
819
826
|
pi-mcp/ Installable Pi package for MCP integration
|
|
820
827
|
pi-lsp/ Installable Pi package for LSP tools
|
|
821
828
|
pi-confirm-destructive/ Installable Pi package for destructive action confirmations
|
|
829
|
+
pi-svelte-guardrails/ Installable Pi package for Svelte pattern guardrails
|
|
822
830
|
pi-skills/ Installable Pi package for skill management
|
|
823
831
|
pi-recall/ Installable Pi package for pirecall reminders
|
|
824
832
|
pi-nopeek/ Installable Pi package for nopeek reminders
|
package/dist/api.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Api, Model } from "@
|
|
2
|
-
import * as _$
|
|
3
|
-
import { AgentSessionRuntime, CreateAgentSessionFromServicesOptions, ExtensionAPI, ExtensionFactory, ExtensionFactory as ExtensionFactory$1, InteractiveMode, InteractiveModeOptions, PrintModeOptions, runPrintMode, runRpcMode } from "@
|
|
1
|
+
import { Api, Model } from "@earendil-works/pi-ai";
|
|
2
|
+
import * as _$_earendil_works_pi_coding_agent0 from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { AgentSessionRuntime, CreateAgentSessionFromServicesOptions, ExtensionAPI, ExtensionFactory, ExtensionFactory as ExtensionFactory$1, InteractiveMode, InteractiveModeOptions, PrintModeOptions, runPrintMode, runRpcMode } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import * as _$_spences10_pi_context0 from "@spences10/pi-context";
|
|
5
5
|
import * as _$_spences10_pi_mcp0 from "@spences10/pi-mcp";
|
|
6
6
|
import * as _$_spences10_pi_skills0 from "@spences10/pi-skills";
|
|
@@ -10,6 +10,7 @@ import * as _$_spences10_pi_nopeek0 from "@spences10/pi-nopeek";
|
|
|
10
10
|
import * as _$_spences10_pi_omnisearch0 from "@spences10/pi-omnisearch";
|
|
11
11
|
import * as _$_spences10_pi_sqlite_tools0 from "@spences10/pi-sqlite-tools";
|
|
12
12
|
import * as _$_spences10_pi_confirm_destructive0 from "@spences10/pi-confirm-destructive";
|
|
13
|
+
import * as _$_spences10_pi_svelte_guardrails0 from "@spences10/pi-svelte-guardrails";
|
|
13
14
|
import * as _$_spences10_pi_team_mode0 from "@spences10/pi-team-mode";
|
|
14
15
|
|
|
15
16
|
//#region src/extensions/startup-screen/index.d.ts
|
|
@@ -157,7 +158,7 @@ declare const BUILTIN_EXTENSION_REGISTRY: readonly [{
|
|
|
157
158
|
readonly cli_flag: "--no-lsp";
|
|
158
159
|
readonly cli_description: "Disable LSP extension";
|
|
159
160
|
readonly aliases: readonly ["lsp", "language-server"];
|
|
160
|
-
readonly load: () => Promise<(pi: _$
|
|
161
|
+
readonly load: () => Promise<(pi: _$_earendil_works_pi_coding_agent0.ExtensionAPI) => Promise<void>>;
|
|
161
162
|
}, {
|
|
162
163
|
readonly key: "session-name";
|
|
163
164
|
readonly label: "Session name";
|
|
@@ -190,7 +191,7 @@ declare const BUILTIN_EXTENSION_REGISTRY: readonly [{
|
|
|
190
191
|
readonly key: "hooks-resolution";
|
|
191
192
|
readonly label: "Hooks resolution";
|
|
192
193
|
readonly docs_label: "Hooks resolution";
|
|
193
|
-
readonly description: "Claude Code style PostToolUse hook compatibility from .claude, .rulesync, and .pi configs";
|
|
194
|
+
readonly description: "Claude Code style PreToolUse and PostToolUse hook compatibility from .claude, .rulesync, and .pi configs";
|
|
194
195
|
readonly default_enabled: true;
|
|
195
196
|
readonly option_name: "hooks_resolution";
|
|
196
197
|
readonly cli_arg: "no-hooks";
|
|
@@ -198,6 +199,18 @@ declare const BUILTIN_EXTENSION_REGISTRY: readonly [{
|
|
|
198
199
|
readonly cli_description: "Disable Claude-style hook execution";
|
|
199
200
|
readonly aliases: readonly ["hooks-resolution", "hooks"];
|
|
200
201
|
readonly load: () => Promise<ExtensionFactory$1>;
|
|
202
|
+
}, {
|
|
203
|
+
readonly key: "svelte-guardrails";
|
|
204
|
+
readonly label: "Svelte guardrails";
|
|
205
|
+
readonly docs_label: "Svelte guardrails";
|
|
206
|
+
readonly description: "Blocks discouraged Svelte patterns like $effect before agents write them";
|
|
207
|
+
readonly default_enabled: true;
|
|
208
|
+
readonly option_name: "svelte_guardrails";
|
|
209
|
+
readonly cli_arg: "no-svelte-guardrails";
|
|
210
|
+
readonly cli_flag: "--no-svelte-guardrails";
|
|
211
|
+
readonly cli_description: "Disable Svelte guardrails";
|
|
212
|
+
readonly aliases: readonly ["svelte-guardrails", "svelte"];
|
|
213
|
+
readonly load: () => Promise<typeof _$_spences10_pi_svelte_guardrails0.default>;
|
|
201
214
|
}, {
|
|
202
215
|
readonly key: "team-mode";
|
|
203
216
|
readonly label: "Team mode";
|
|
@@ -237,7 +250,6 @@ interface CreateMyPiOptions extends BuiltinExtensionOptions {
|
|
|
237
250
|
}
|
|
238
251
|
type BuiltinExtensionLoader = () => Promise<ExtensionFactory$1>;
|
|
239
252
|
declare function apply_untrusted_repo_defaults(env?: NodeJS.ProcessEnv): string[];
|
|
240
|
-
declare function is_project_local_skill_path(cwd: string, file_path: string | undefined): boolean;
|
|
241
253
|
interface ModelRegistryLike {
|
|
242
254
|
getAll(): Model<Api>[];
|
|
243
255
|
}
|
|
@@ -245,7 +257,7 @@ declare function resolve_model_reference(model_reference: string | undefined, mo
|
|
|
245
257
|
declare function resolve_effective_thinking_level(model: Model<Api> | undefined, thinking: MyPiThinkingLevel | undefined): MyPiThinkingLevel | undefined;
|
|
246
258
|
declare function get_force_disabled_builtins(options: Pick<CreateMyPiOptions, 'runtime_mode'> & BuiltinExtensionOptions): ReadonlySet<BuiltinExtensionKey>;
|
|
247
259
|
declare function create_lazy_builtin_extension_factory(key: BuiltinExtensionKey, load_extension: BuiltinExtensionLoader, force_disabled: ReadonlySet<BuiltinExtensionKey>): ExtensionFactory$1;
|
|
248
|
-
declare function create_my_pi(options?: CreateMyPiOptions): Promise<_$
|
|
260
|
+
declare function create_my_pi(options?: CreateMyPiOptions): Promise<_$_earendil_works_pi_coding_agent0.AgentSessionRuntime>;
|
|
249
261
|
//#endregion
|
|
250
|
-
export { type AgentSessionRuntime, CreateMyPiOptions, type ExtensionFactory, InteractiveMode, type InteractiveModeOptions, MyPiRuntimeMode, MyPiThinkingLevel, type PrintModeOptions, apply_untrusted_repo_defaults, create_lazy_builtin_extension_factory, create_my_pi, get_force_disabled_builtins,
|
|
262
|
+
export { type AgentSessionRuntime, CreateMyPiOptions, type ExtensionFactory, InteractiveMode, type InteractiveModeOptions, MyPiRuntimeMode, MyPiThinkingLevel, type PrintModeOptions, apply_untrusted_repo_defaults, create_lazy_builtin_extension_factory, create_my_pi, get_force_disabled_builtins, resolve_effective_thinking_level, resolve_model_reference, runPrintMode, runRpcMode };
|
|
251
263
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as BUILTIN_EXTENSION_REGISTRY, t as BUILTIN_EXTENSIONS } from "./builtin-registry-
|
|
1
|
+
import { n as BUILTIN_EXTENSION_REGISTRY, t as BUILTIN_EXTENSIONS } from "./builtin-registry-1hIf07ru.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { dirname,
|
|
5
|
-
import { clampThinkingLevel } from "@
|
|
6
|
-
import { InteractiveMode, SessionManager, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, runPrintMode, runRpcMode } from "@
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { clampThinkingLevel } from "@earendil-works/pi-ai";
|
|
6
|
+
import { InteractiveMode, SessionManager, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, runPrintMode, runRpcMode } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import { apply_project_trust_untrusted_defaults } from "@spences10/pi-project-trust";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { show_settings_modal } from "@spences10/pi-tui-modal";
|
|
@@ -303,13 +303,6 @@ function is_resource_enabled(value) {
|
|
|
303
303
|
].includes(normalized)) return false;
|
|
304
304
|
return true;
|
|
305
305
|
}
|
|
306
|
-
function is_project_local_skill_path(cwd, file_path) {
|
|
307
|
-
if (!file_path) return false;
|
|
308
|
-
const relative_path = relative(cwd, resolve(cwd, file_path));
|
|
309
|
-
if (!relative_path || relative_path.startsWith("..") || isAbsolute(relative_path)) return false;
|
|
310
|
-
const parts = relative_path.split(/[\\/]+/);
|
|
311
|
-
return parts.some((part, index) => (part === ".pi" || part === ".claude") && parts[index + 1] === "skills");
|
|
312
|
-
}
|
|
313
306
|
function resolve_agent_dir(cwd, agent_dir) {
|
|
314
307
|
return agent_dir ? resolve(cwd, agent_dir) : getAgentDir();
|
|
315
308
|
}
|
|
@@ -406,11 +399,16 @@ async function create_my_pi(options = {}) {
|
|
|
406
399
|
];
|
|
407
400
|
const managed_inline_paths = managed_extension_factories.map((_, index) => `<inline:${index + 1}>`);
|
|
408
401
|
const create_runtime = async ({ cwd: runtime_cwd, sessionManager, sessionStartEvent }) => {
|
|
409
|
-
const runtime_skills_manager = skills_package?.create_skills_manager(
|
|
402
|
+
const runtime_skills_manager = skills_package?.create_skills_manager({
|
|
403
|
+
cwd: runtime_cwd,
|
|
404
|
+
project_skills_enabled: is_resource_enabled(process.env.MY_PI_PROJECT_SKILLS)
|
|
405
|
+
});
|
|
406
|
+
const additional_skill_paths = runtime_skills_manager?.get_enabled_skill_paths() ?? [];
|
|
410
407
|
const services = await createAgentSessionServices({
|
|
411
408
|
cwd: runtime_cwd,
|
|
412
409
|
agentDir: effective_agent_dir,
|
|
413
410
|
resourceLoaderOptions: {
|
|
411
|
+
...additional_skill_paths.length ? { additionalSkillPaths: additional_skill_paths } : {},
|
|
414
412
|
...system_prompt !== void 0 ? { systemPromptOverride: () => system_prompt } : {},
|
|
415
413
|
...append_system_prompt !== void 0 ? { appendSystemPromptOverride: (base) => [...base, append_system_prompt] } : {},
|
|
416
414
|
additionalExtensionPaths: [...resolved_extensions],
|
|
@@ -420,12 +418,10 @@ async function create_my_pi(options = {}) {
|
|
|
420
418
|
skillsOverride: (base) => {
|
|
421
419
|
if (!runtime_skills_manager) return base;
|
|
422
420
|
runtime_skills_manager.refresh();
|
|
423
|
-
const include_project_skills = is_resource_enabled(process.env.MY_PI_PROJECT_SKILLS);
|
|
424
421
|
const selected_skill_names = selected_skills?.length ? new Set(selected_skills) : void 0;
|
|
425
422
|
return {
|
|
426
423
|
...base,
|
|
427
424
|
skills: base.skills.filter((skill) => {
|
|
428
|
-
if (!include_project_skills && is_project_local_skill_path(runtime_cwd, skill.filePath)) return false;
|
|
429
425
|
if (selected_skill_names && !selected_skill_names.has(skill.name)) return false;
|
|
430
426
|
return runtime_skills_manager.is_enabled_by_skill(skill.name, skill.filePath);
|
|
431
427
|
})
|
|
@@ -464,6 +460,6 @@ async function create_my_pi(options = {}) {
|
|
|
464
460
|
}
|
|
465
461
|
}
|
|
466
462
|
//#endregion
|
|
467
|
-
export { InteractiveMode, apply_untrusted_repo_defaults, create_lazy_builtin_extension_factory, create_my_pi, get_force_disabled_builtins,
|
|
463
|
+
export { InteractiveMode, apply_untrusted_repo_defaults, create_lazy_builtin_extension_factory, create_my_pi, get_force_disabled_builtins, resolve_effective_thinking_level, resolve_model_reference, runPrintMode, runRpcMode };
|
|
468
464
|
|
|
469
465
|
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":[],"sources":["../src/extensions/manager/config.ts","../src/extensions/manager/index.ts","../src/api.ts"],"sourcesContent":["import {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\trenameSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport {\n\tBUILTIN_EXTENSIONS,\n\ttype BuiltinExtensionInfo,\n\ttype BuiltinExtensionKey,\n} from '../builtin-registry.js';\n\nexport { BUILTIN_EXTENSIONS };\nexport type { BuiltinExtensionInfo, BuiltinExtensionKey };\n\nexport interface BuiltinExtensionsConfig {\n\tversion: number;\n\tenabled: Partial<Record<BuiltinExtensionKey, boolean>>;\n}\n\nexport interface BuiltinExtensionState extends BuiltinExtensionInfo {\n\tsaved_enabled: boolean;\n\teffective_enabled: boolean;\n\tforced_disabled: boolean;\n}\n\nconst DEFAULT_CONFIG: BuiltinExtensionsConfig = {\n\tversion: 1,\n\tenabled: {},\n};\n\nexport function get_builtin_extensions_config_path(): string {\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn join(xdg, 'my-pi', 'extensions.json');\n}\n\nexport function load_builtin_extensions_config(): BuiltinExtensionsConfig {\n\tconst path = get_builtin_extensions_config_path();\n\tif (!existsSync(path)) return { ...DEFAULT_CONFIG };\n\n\ttry {\n\t\tconst raw = readFileSync(path, 'utf-8');\n\t\tconst parsed = JSON.parse(\n\t\t\traw,\n\t\t) as Partial<BuiltinExtensionsConfig>;\n\t\tconst enabled: BuiltinExtensionsConfig['enabled'] = {};\n\t\tfor (const extension of BUILTIN_EXTENSIONS) {\n\t\t\tconst value = parsed.enabled?.[extension.key];\n\t\t\tif (typeof value === 'boolean') {\n\t\t\t\tenabled[extension.key] = value;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tversion: parsed.version ?? 1,\n\t\t\tenabled,\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\nexport function save_builtin_extensions_config(\n\tconfig: BuiltinExtensionsConfig,\n): void {\n\tconst path = get_builtin_extensions_config_path();\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n\n\tconst tmp = `${path}.tmp-${Date.now()}`;\n\twriteFileSync(tmp, JSON.stringify(config, null, '\\t') + '\\n', {\n\t\tmode: 0o600,\n\t});\n\trenameSync(tmp, path);\n}\n\nexport function is_builtin_extension_enabled(\n\tconfig: BuiltinExtensionsConfig,\n\tkey: BuiltinExtensionKey,\n): boolean {\n\treturn config.enabled[key] ?? true;\n}\n\nexport function is_builtin_extension_active(\n\tconfig: BuiltinExtensionsConfig,\n\tkey: BuiltinExtensionKey,\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey> = new Set(),\n): boolean {\n\treturn (\n\t\tis_builtin_extension_enabled(config, key) &&\n\t\t!force_disabled.has(key)\n\t);\n}\n\nexport function resolve_builtin_extension_states(\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey> = new Set(),\n\tconfig: BuiltinExtensionsConfig = load_builtin_extensions_config(),\n): BuiltinExtensionState[] {\n\treturn BUILTIN_EXTENSIONS.map((extension) => {\n\t\tconst saved_enabled = is_builtin_extension_enabled(\n\t\t\tconfig,\n\t\t\textension.key,\n\t\t);\n\t\tconst forced = force_disabled.has(extension.key);\n\t\treturn {\n\t\t\t...extension,\n\t\t\tsaved_enabled,\n\t\t\teffective_enabled: saved_enabled && !forced,\n\t\t\tforced_disabled: forced,\n\t\t};\n\t});\n}\n\nexport function find_builtin_extension(\n\tquery: string,\n): BuiltinExtensionInfo | undefined {\n\tconst normalized = query.trim().toLowerCase();\n\tif (!normalized) return undefined;\n\n\treturn BUILTIN_EXTENSIONS.find((extension) =>\n\t\t[extension.key, extension.label, ...extension.aliases].some(\n\t\t\t(value) => value.toLowerCase() === normalized,\n\t\t),\n\t);\n}\n","import type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n} from '@mariozechner/pi-coding-agent';\nimport { type SettingItem } from '@mariozechner/pi-tui';\nimport { show_settings_modal } from '@spences10/pi-tui-modal';\nimport {\n\tBUILTIN_EXTENSIONS,\n\tfind_builtin_extension,\n\tload_builtin_extensions_config,\n\tresolve_builtin_extension_states,\n\tsave_builtin_extensions_config,\n\ttype BuiltinExtensionKey,\n\ttype BuiltinExtensionState,\n} from './config.js';\n\nconst ENABLED = '● enabled';\nconst DISABLED = '○ disabled';\n\nexport interface ExtensionsManagerOptions {\n\tforce_disabled?: Iterable<BuiltinExtensionKey>;\n}\n\nfunction to_force_disabled_set(\n\tforce_disabled?: Iterable<BuiltinExtensionKey>,\n): ReadonlySet<BuiltinExtensionKey> {\n\treturn new Set(force_disabled ?? []);\n}\n\nfunction format_effective_state(\n\tstate: BuiltinExtensionState,\n): string {\n\tif (state.effective_enabled) {\n\t\treturn 'enabled';\n\t}\n\tif (state.forced_disabled) {\n\t\treturn `disabled in this process by ${state.cli_flag}`;\n\t}\n\treturn 'disabled';\n}\n\nfunction format_extension_lines(\n\tstates: BuiltinExtensionState[],\n\toptions?: { heading?: string },\n): string {\n\tconst lines: string[] = [];\n\tif (options?.heading) {\n\t\tlines.push(options.heading, '');\n\t}\n\n\tconst enabled_now = states.filter(\n\t\t(state) => state.effective_enabled,\n\t).length;\n\tconst disabled_now = states.length - enabled_now;\n\tlines.push(\n\t\t`${states.length} built-in extensions (${enabled_now} enabled now, ${disabled_now} disabled now)`,\n\t\t'',\n\t);\n\n\tfor (const state of states) {\n\t\tlines.push(\n\t\t\t`${state.saved_enabled ? ENABLED : DISABLED} ${state.label}`,\n\t\t);\n\t\tlines.push(` key: ${state.key}`);\n\t\tlines.push(\n\t\t\t` saved config: ${state.saved_enabled ? 'enabled' : 'disabled'}`,\n\t\t);\n\t\tlines.push(\n\t\t\t` current process: ${format_effective_state(state)}`,\n\t\t);\n\t\tlines.push(` ${state.description}`);\n\t}\n\n\treturn lines.join('\\n');\n}\n\nfunction to_setting_item(state: BuiltinExtensionState): SettingItem {\n\tconst detail_lines = [\n\t\tstate.key,\n\t\tstate.description,\n\t\t`current process: ${format_effective_state(state)}`,\n\t\t`startup override: ${state.cli_flag}`,\n\t];\n\n\treturn {\n\t\tid: state.key,\n\t\tlabel: state.label,\n\t\tdescription: detail_lines.join('\\n'),\n\t\tcurrentValue: state.saved_enabled ? ENABLED : DISABLED,\n\t\tvalues: [ENABLED, DISABLED],\n\t};\n}\n\nfunction sets_equal(\n\ta: ReadonlySet<string>,\n\tb: ReadonlySet<string>,\n): boolean {\n\tif (a.size !== b.size) return false;\n\tfor (const value of a) {\n\t\tif (!b.has(value)) return false;\n\t}\n\treturn true;\n}\n\nfunction search_states(\n\tstates: BuiltinExtensionState[],\n\tquery: string,\n): BuiltinExtensionState[] {\n\tconst normalized = query.trim().toLowerCase();\n\tif (!normalized) return states;\n\n\treturn states.filter((state) =>\n\t\t[\n\t\t\tstate.key,\n\t\t\tstate.label,\n\t\t\tstate.description,\n\t\t\t...state.aliases,\n\t\t].some((value) => value.toLowerCase().includes(normalized)),\n\t);\n}\n\nfunction save_extension_enabled(\n\tkey: BuiltinExtensionKey,\n\tenabled: boolean,\n): void {\n\tconst config = load_builtin_extensions_config();\n\tconfig.enabled[key] = enabled;\n\tsave_builtin_extensions_config(config);\n}\n\nexport function create_extensions_extension(\n\toptions: ExtensionsManagerOptions = {},\n) {\n\tconst force_disabled = to_force_disabled_set(\n\t\toptions.force_disabled,\n\t);\n\n\tasync function show_manager(\n\t\tctx: ExtensionCommandContext,\n\t): Promise<boolean> {\n\t\tif (!ctx.hasUI) return false;\n\n\t\tconst states = resolve_builtin_extension_states(force_disabled);\n\t\tconst initial_enabled = new Set(\n\t\t\tstates\n\t\t\t\t.filter((state) => state.saved_enabled)\n\t\t\t\t.map((state) => state.key),\n\t\t);\n\t\tconst current_enabled = new Set(initial_enabled);\n\n\t\tconst items = states.map(to_setting_item);\n\t\tawait show_settings_modal(ctx, {\n\t\t\ttitle: 'Built-in extensions',\n\t\t\tsubtitle: () => {\n\t\t\t\tconst saved_enabled = current_enabled.size;\n\t\t\t\tconst saved_disabled = states.length - saved_enabled;\n\t\t\t\tconst enabled_now = [...current_enabled].filter(\n\t\t\t\t\t(key) => !force_disabled.has(key as BuiltinExtensionKey),\n\t\t\t\t).length;\n\t\t\t\tconst disabled_now = states.length - enabled_now;\n\t\t\t\treturn `${saved_enabled} saved enabled • ${saved_disabled} saved disabled • ${enabled_now} enabled now • ${disabled_now} disabled now`;\n\t\t\t},\n\t\t\titems,\n\t\t\tenable_search: true,\n\t\t\tfooter:\n\t\t\t\t'esc close • search filters • changes save immediately • CLI --no-* flags still win in this process',\n\t\t\ton_change: (id, new_value) => {\n\t\t\t\tconst key = id as BuiltinExtensionKey;\n\t\t\t\tconst enabled = new_value === ENABLED;\n\t\t\t\tif (enabled) {\n\t\t\t\t\tcurrent_enabled.add(key);\n\t\t\t\t} else {\n\t\t\t\t\tcurrent_enabled.delete(key);\n\t\t\t\t}\n\t\t\t\tsave_extension_enabled(key, enabled);\n\t\t\t},\n\t\t});\n\n\t\tif (!sets_equal(initial_enabled, current_enabled)) {\n\t\t\tctx.ui.notify(\n\t\t\t\tforce_disabled.size > 0\n\t\t\t\t\t? 'Reloading to apply updated built-in extensions. CLI --no-* flags still force-disable some extensions in this process.'\n\t\t\t\t\t: 'Reloading to apply updated built-in extensions...',\n\t\t\t\t'info',\n\t\t\t);\n\t\t\tawait ctx.reload();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\treturn async function extensions(pi: ExtensionAPI) {\n\t\tconst subs = ['list', 'enable', 'disable', 'toggle', 'search'];\n\n\t\tpi.registerCommand('extensions', {\n\t\t\tdescription: 'Manage built-in my-pi extensions',\n\t\t\tgetArgumentCompletions: (prefix) => {\n\t\t\t\tconst parts = prefix.trim().split(/\\s+/);\n\t\t\t\tif (parts.length <= 1) {\n\t\t\t\t\treturn subs\n\t\t\t\t\t\t.filter((sub) => sub.startsWith(parts[0] || ''))\n\t\t\t\t\t\t.map((sub) => ({ value: sub, label: sub }));\n\t\t\t\t}\n\n\t\t\t\tif (['enable', 'disable', 'toggle'].includes(parts[0])) {\n\t\t\t\t\tconst q = parts.slice(1).join(' ').toLowerCase();\n\t\t\t\t\treturn resolve_builtin_extension_states(force_disabled)\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(state) =>\n\t\t\t\t\t\t\t\tstate.key.toLowerCase().includes(q) ||\n\t\t\t\t\t\t\t\tstate.label.toLowerCase().includes(q),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.slice(0, 20)\n\t\t\t\t\t\t.map((state) => ({\n\t\t\t\t\t\t\tvalue: `${parts[0]} ${state.key}`,\n\t\t\t\t\t\t\tlabel: `${state.key} ${state.saved_enabled ? ENABLED : DISABLED}`,\n\t\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (await show_manager(ctx)) return;\n\t\t\t\t}\n\n\t\t\t\tconst [sub, ...rest] = (trimmed || 'list').split(/\\s+/);\n\t\t\t\tconst arg = rest.join(' ');\n\t\t\t\tconst states =\n\t\t\t\t\tresolve_builtin_extension_states(force_disabled);\n\n\t\t\t\tswitch (sub) {\n\t\t\t\t\tcase 'list': {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tformat_extension_lines(states, {\n\t\t\t\t\t\t\t\theading: 'Built-in extensions',\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'enable':\n\t\t\t\t\tcase 'disable':\n\t\t\t\t\tcase 'toggle': {\n\t\t\t\t\t\tif (!arg) {\n\t\t\t\t\t\t\tif (await show_manager(ctx)) return;\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`Usage: /extensions ${sub} <key>`,\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst extension = find_builtin_extension(arg);\n\t\t\t\t\t\tif (!extension) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`Unknown extension: ${arg}. Use: ${BUILTIN_EXTENSIONS.map((item) => item.key).join(', ')}`,\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst current_state = states.find(\n\t\t\t\t\t\t\t(state) => state.key === extension.key,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst next_enabled =\n\t\t\t\t\t\t\tsub === 'enable'\n\t\t\t\t\t\t\t\t? true\n\t\t\t\t\t\t\t\t: sub === 'disable'\n\t\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t\t: !current_state?.saved_enabled;\n\t\t\t\t\t\tsave_extension_enabled(extension.key, next_enabled);\n\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tnext_enabled && force_disabled.has(extension.key)\n\t\t\t\t\t\t\t\t? `Enabled ${extension.key} in saved config. Still disabled in this process by ${extension.cli_flag}. /reload or restart without that flag to apply.`\n\t\t\t\t\t\t\t\t: `${extension.key} ${next_enabled ? 'enabled' : 'disabled'}. /reload to apply.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'search': {\n\t\t\t\t\t\tif (!arg) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t'Usage: /extensions search <query>',\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst results = search_states(states, arg);\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`No built-in extensions matching \"${arg}\"`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tformat_extension_lines(results, {\n\t\t\t\t\t\t\t\theading: `Built-in extensions matching \"${arg}\"`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Unknown: ${sub}. Use: ${subs.join(', ')}`,\n\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n\nexport default create_extensions_extension();\n","// Composable programmatic API for my-pi\n// Extension loading patterns inspired by pi-vs-claude-code\n\nimport {\n\tclampThinkingLevel,\n\ttype Api,\n\ttype Model,\n} from '@mariozechner/pi-ai';\nimport {\n\tInteractiveMode,\n\tSessionManager,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionRuntime,\n\tcreateAgentSessionServices,\n\tgetAgentDir,\n\trunPrintMode,\n\trunRpcMode,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype ExtensionFactory,\n\ttype LoadExtensionsResult,\n} from '@mariozechner/pi-coding-agent';\nimport { apply_project_trust_untrusted_defaults } from '@spences10/pi-project-trust';\nimport { createRequire } from 'node:module';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport {\n\tBUILTIN_EXTENSION_REGISTRY,\n\ttype BuiltinExtensionKey,\n\ttype BuiltinExtensionOptionName,\n} from './extensions/builtin-registry.js';\nimport {\n\tis_builtin_extension_active,\n\tload_builtin_extensions_config,\n} from './extensions/manager/config.js';\nimport { create_extensions_extension } from './extensions/manager/index.js';\n\nexport type MyPiRuntimeMode =\n\t| 'interactive'\n\t| 'print'\n\t| 'json'\n\t| 'rpc';\n\nexport type MyPiThinkingLevel = NonNullable<\n\tCreateAgentSessionFromServicesOptions['thinkingLevel']\n>;\n\ntype BuiltinExtensionOptions = Partial<\n\tRecord<BuiltinExtensionOptionName, boolean>\n>;\n\nexport interface CreateMyPiOptions extends BuiltinExtensionOptions {\n\tcwd?: string;\n\tagent_dir?: string;\n\textensions?: string[];\n\textensionFactories?: ExtensionFactory[];\n\truntime_mode?: MyPiRuntimeMode;\n\ttelemetry?: boolean;\n\ttelemetry_db_path?: string;\n\tmodel?: string;\n\tthinking?: MyPiThinkingLevel;\n\tselected_tools?: string[];\n\tselected_skills?: string[];\n\tsession_dir?: string;\n\tsystem_prompt?: string;\n\tappend_system_prompt?: string;\n\tuntrusted_repo?: boolean;\n}\n\ntype BuiltinExtensionLoader = () => Promise<ExtensionFactory>;\n\nconst require = createRequire(import.meta.url);\nconst PACKAGE_THEME_DIR = resolve(\n\tdirname(require.resolve('@spences10/pi-themes/package.json')),\n\t'themes',\n);\nconst PI_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nconst MY_PI_RUNTIME_MODE_ENV = 'MY_PI_RUNTIME_MODE';\n\ntype EnvSnapshot = Map<string, string | undefined>;\n\nfunction snapshot_env(\n\tenv: NodeJS.ProcessEnv,\n\tkeys: Iterable<string>,\n): EnvSnapshot {\n\treturn new Map(Array.from(keys, (key) => [key, env[key]]));\n}\n\nfunction restore_env(\n\tenv: NodeJS.ProcessEnv,\n\tsnapshot: EnvSnapshot,\n): void {\n\tfor (const [key, value] of snapshot) {\n\t\tif (value === undefined) delete env[key];\n\t\telse env[key] = value;\n\t}\n}\n\nfunction wrap_runtime_env_restore<\n\tT extends { dispose(): Promise<void> },\n>(runtime: T, restore: () => void): T {\n\tconst dispose = runtime.dispose.bind(runtime);\n\tlet restored = false;\n\tconst restore_once = () => {\n\t\tif (restored) return;\n\t\trestored = true;\n\t\trestore();\n\t};\n\n\truntime.dispose = (async () => {\n\t\ttry {\n\t\t\tawait dispose();\n\t\t} finally {\n\t\t\trestore_once();\n\t\t}\n\t}) as T['dispose'];\n\n\treturn runtime;\n}\n\nconst UNTRUSTED_CHILD_ENV_DEFAULTS: Record<string, string> = {\n\tMY_PI_CHILD_ENV_ALLOWLIST: '',\n\tMY_PI_MCP_ENV_ALLOWLIST: '',\n\tMY_PI_LSP_ENV_ALLOWLIST: '',\n\tMY_PI_HOOKS_ENV_ALLOWLIST: '',\n\tMY_PI_TEAM_MODE_ENV_ALLOWLIST: '',\n};\n\nexport function apply_untrusted_repo_defaults(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string[] {\n\tconst applied = apply_project_trust_untrusted_defaults(env);\n\tfor (const [key, value] of Object.entries(\n\t\tUNTRUSTED_CHILD_ENV_DEFAULTS,\n\t)) {\n\t\tif (env[key] !== undefined) continue;\n\t\tenv[key] = value;\n\t\tapplied.push(key);\n\t}\n\treturn applied;\n}\n\nfunction is_resource_enabled(value: string | undefined): boolean {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (!normalized) return true;\n\tif (['0', 'false', 'no', 'skip', 'disable'].includes(normalized)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function is_project_local_skill_path(\n\tcwd: string,\n\tfile_path: string | undefined,\n): boolean {\n\tif (!file_path) return false;\n\tconst absolute = resolve(cwd, file_path);\n\tconst relative_path = relative(cwd, absolute);\n\tif (\n\t\t!relative_path ||\n\t\trelative_path.startsWith('..') ||\n\t\tisAbsolute(relative_path)\n\t) {\n\t\treturn false;\n\t}\n\tconst parts = relative_path.split(/[\\\\/]+/);\n\treturn parts.some(\n\t\t(part, index) =>\n\t\t\t(part === '.pi' || part === '.claude') &&\n\t\t\tparts[index + 1] === 'skills',\n\t);\n}\n\nfunction resolve_agent_dir(cwd: string, agent_dir?: string): string {\n\treturn agent_dir ? resolve(cwd, agent_dir) : getAgentDir();\n}\n\ninterface ModelRegistryLike {\n\tgetAll(): Model<Api>[];\n}\n\nexport function resolve_model_reference(\n\tmodel_reference: string | undefined,\n\tmodel_registry: ModelRegistryLike,\n): Model<Api> | undefined {\n\tif (!model_reference) return undefined;\n\tconst models = model_registry.getAll();\n\tconst lower_reference = model_reference.toLowerCase();\n\tconst slash_index = model_reference.indexOf('/');\n\n\tif (slash_index !== -1) {\n\t\tconst maybe_provider = model_reference.slice(0, slash_index);\n\t\tconst model_id = model_reference.slice(slash_index + 1);\n\t\tconst provider = models.find(\n\t\t\t(model) =>\n\t\t\t\tmodel.provider.toLowerCase() === maybe_provider.toLowerCase(),\n\t\t)?.provider;\n\n\t\tif (provider) {\n\t\t\tconst provider_match = models.find(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider === provider &&\n\t\t\t\t\tmodel.id.toLowerCase() === model_id.toLowerCase(),\n\t\t\t);\n\t\t\tif (provider_match) return provider_match;\n\t\t}\n\t}\n\n\treturn models.find((model) => {\n\t\tconst id = model.id.toLowerCase();\n\t\tconst full_id = `${model.provider}/${model.id}`.toLowerCase();\n\t\treturn id === lower_reference || full_id === lower_reference;\n\t});\n}\n\nexport function resolve_effective_thinking_level(\n\tmodel: Model<Api> | undefined,\n\tthinking: MyPiThinkingLevel | undefined,\n): MyPiThinkingLevel | undefined {\n\tif (!thinking || !model) return thinking;\n\treturn clampThinkingLevel(model, thinking);\n}\n\nexport function get_force_disabled_builtins(\n\toptions: Pick<CreateMyPiOptions, 'runtime_mode'> &\n\t\tBuiltinExtensionOptions,\n): ReadonlySet<BuiltinExtensionKey> {\n\tconst force_disabled = new Set<BuiltinExtensionKey>();\n\tfor (const extension of BUILTIN_EXTENSION_REGISTRY) {\n\t\tconst enabled =\n\t\t\toptions[extension.option_name] ?? extension.default_enabled;\n\t\tif (!enabled) force_disabled.add(extension.key);\n\t\tconst disabled_in =\n\t\t\t'mode_constraints' in extension\n\t\t\t\t? extension.mode_constraints.disabled_in\n\t\t\t\t: undefined;\n\t\tif (\n\t\t\toptions.runtime_mode &&\n\t\t\t(\n\t\t\t\tdisabled_in as readonly MyPiRuntimeMode[] | undefined\n\t\t\t)?.includes(options.runtime_mode)\n\t\t) {\n\t\t\tforce_disabled.add(extension.key);\n\t\t}\n\t}\n\treturn force_disabled;\n}\n\nexport function create_lazy_builtin_extension_factory(\n\tkey: BuiltinExtensionKey,\n\tload_extension: BuiltinExtensionLoader,\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey>,\n): ExtensionFactory {\n\treturn async (pi) => {\n\t\tconst config = load_builtin_extensions_config();\n\t\tif (!is_builtin_extension_active(config, key, force_disabled)) {\n\t\t\treturn;\n\t\t}\n\t\tconst extension = await load_extension();\n\t\tawait extension(pi);\n\t};\n}\n\nfunction create_lazy_telemetry_extension(options: {\n\tenabled?: boolean;\n\tdb_path?: string;\n\tcwd?: string;\n}): ExtensionFactory {\n\treturn async (pi) => {\n\t\tconst { create_telemetry_extension } =\n\t\t\tawait import('@spences10/pi-telemetry');\n\t\tawait create_telemetry_extension(options)(pi);\n\t};\n}\n\nfunction create_extensions_override(\n\tmanaged_inline_paths: string[],\n): (base: LoadExtensionsResult) => LoadExtensionsResult {\n\tconst managed_paths = new Set(managed_inline_paths);\n\treturn (base) => {\n\t\tconst managed = new Map(\n\t\t\tbase.extensions.map((extension) => [extension.path, extension]),\n\t\t);\n\t\tconst ordered_managed = managed_inline_paths\n\t\t\t.map((path) => managed.get(path))\n\t\t\t.filter(\n\t\t\t\t(\n\t\t\t\t\textension,\n\t\t\t\t): extension is LoadExtensionsResult['extensions'][number] =>\n\t\t\t\t\tBoolean(extension),\n\t\t\t);\n\t\tconst others = base.extensions.filter(\n\t\t\t(extension) => !managed_paths.has(extension.path),\n\t\t);\n\t\treturn {\n\t\t\t...base,\n\t\t\textensions: [...ordered_managed, ...others],\n\t\t};\n\t};\n}\n\nexport async function create_my_pi(options: CreateMyPiOptions = {}) {\n\tconst {\n\t\tcwd = process.cwd(),\n\t\tagent_dir,\n\t\textensions = [],\n\t\textensionFactories: user_factories = [],\n\t\truntime_mode = 'interactive',\n\t\ttelemetry,\n\t\ttelemetry_db_path,\n\t\tmodel,\n\t\tthinking,\n\t\tselected_tools,\n\t\tselected_skills,\n\t\tsession_dir,\n\t\tsystem_prompt,\n\t\tappend_system_prompt,\n\t\tuntrusted_repo = false,\n\t} = options;\n\n\tconst env_keys_to_restore = new Set<string>([\n\t\tMY_PI_RUNTIME_MODE_ENV,\n\t]);\n\tif (agent_dir) env_keys_to_restore.add(PI_AGENT_DIR_ENV);\n\tconst env_snapshot = snapshot_env(process.env, env_keys_to_restore);\n\tlet restore_runtime_env = () =>\n\t\trestore_env(process.env, env_snapshot);\n\n\tif (untrusted_repo) {\n\t\tconst applied = apply_untrusted_repo_defaults();\n\t\tif (applied.length) {\n\t\t\tconst restore_previous = restore_runtime_env;\n\t\t\trestore_runtime_env = () => {\n\t\t\t\tfor (const key of applied) delete process.env[key];\n\t\t\t\trestore_previous();\n\t\t\t};\n\t\t}\n\t}\n\n\tconst effective_agent_dir = resolve_agent_dir(cwd, agent_dir);\n\tif (agent_dir) {\n\t\tprocess.env[PI_AGENT_DIR_ENV] = effective_agent_dir;\n\t}\n\tprocess.env[MY_PI_RUNTIME_MODE_ENV] = runtime_mode;\n\n\tconst resolved_extensions = extensions.map((p) => resolve(cwd, p));\n\tconst force_disabled = get_force_disabled_builtins({\n\t\t...options,\n\t\truntime_mode,\n\t});\n\tconst builtins_config = load_builtin_extensions_config();\n\tconst skills_builtin_enabled = is_builtin_extension_active(\n\t\tbuiltins_config,\n\t\t'skills',\n\t\tforce_disabled,\n\t);\n\tconst skills_package = skills_builtin_enabled\n\t\t? await import('@spences10/pi-skills')\n\t\t: undefined;\n\n\tconst managed_extension_factories: ExtensionFactory[] = [\n\t\tcreate_lazy_telemetry_extension({\n\t\t\tenabled: telemetry,\n\t\t\tdb_path: telemetry_db_path,\n\t\t\tcwd,\n\t\t}),\n\t\tcreate_extensions_extension({ force_disabled }),\n\t\t...BUILTIN_EXTENSION_REGISTRY.map((extension) =>\n\t\t\tcreate_lazy_builtin_extension_factory(\n\t\t\t\textension.key,\n\t\t\t\textension.load,\n\t\t\t\tforce_disabled,\n\t\t\t),\n\t\t),\n\t];\n\tconst managed_inline_paths = managed_extension_factories.map(\n\t\t(_, index) => `<inline:${index + 1}>`,\n\t);\n\n\tconst create_runtime = async ({\n\t\tcwd: runtime_cwd,\n\t\tsessionManager,\n\t\tsessionStartEvent,\n\t}: {\n\t\tcwd: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: unknown;\n\t}) => {\n\t\t// Keep skill filtering reloadable so profile changes made by\n\t\t// /skills are reflected without restarting the process.\n\t\tconst runtime_skills_manager =\n\t\t\tskills_package?.create_skills_manager();\n\n\t\tconst services = await createAgentSessionServices({\n\t\t\tcwd: runtime_cwd,\n\t\t\tagentDir: effective_agent_dir,\n\t\t\tresourceLoaderOptions: {\n\t\t\t\t...(system_prompt !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tsystemPromptOverride: () => system_prompt,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t...(append_system_prompt !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tappendSystemPromptOverride: (base: string[]) => [\n\t\t\t\t\t\t\t\t...base,\n\t\t\t\t\t\t\t\tappend_system_prompt,\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tadditionalExtensionPaths: [...resolved_extensions],\n\t\t\t\t...(runtime_mode === 'interactive'\n\t\t\t\t\t? { additionalThemePaths: [PACKAGE_THEME_DIR] }\n\t\t\t\t\t: {}),\n\t\t\t\textensionFactories: [\n\t\t\t\t\t...managed_extension_factories,\n\t\t\t\t\t...user_factories,\n\t\t\t\t],\n\t\t\t\textensionsOverride: create_extensions_override(\n\t\t\t\t\tmanaged_inline_paths,\n\t\t\t\t),\n\t\t\t\tskillsOverride: (base: any) => {\n\t\t\t\t\tif (!runtime_skills_manager) return base;\n\t\t\t\t\truntime_skills_manager.refresh();\n\n\t\t\t\t\tconst include_project_skills = is_resource_enabled(\n\t\t\t\t\t\tprocess.env.MY_PI_PROJECT_SKILLS,\n\t\t\t\t\t);\n\t\t\t\t\tconst selected_skill_names = selected_skills?.length\n\t\t\t\t\t\t? new Set(selected_skills)\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...base,\n\t\t\t\t\t\tskills: base.skills.filter((skill: any) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!include_project_skills &&\n\t\t\t\t\t\t\t\tis_project_local_skill_path(\n\t\t\t\t\t\t\t\t\truntime_cwd,\n\t\t\t\t\t\t\t\t\tskill.filePath,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tselected_skill_names &&\n\t\t\t\t\t\t\t\t!selected_skill_names.has(skill.name)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn runtime_skills_manager.is_enabled_by_skill(\n\t\t\t\t\t\t\t\tskill.name,\n\t\t\t\t\t\t\t\tskill.filePath,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t} as any,\n\t\t});\n\n\t\tconst requested_model = resolve_model_reference(\n\t\t\tmodel,\n\t\t\tservices.modelRegistry,\n\t\t);\n\t\tconst effective_thinking = resolve_effective_thinking_level(\n\t\t\trequested_model,\n\t\t\tthinking,\n\t\t);\n\t\tif (\n\t\t\trequested_model &&\n\t\t\tthinking &&\n\t\t\teffective_thinking &&\n\t\t\teffective_thinking !== thinking\n\t\t) {\n\t\t\tservices.diagnostics.push({\n\t\t\t\ttype: 'warning',\n\t\t\t\tmessage: `Requested thinking level \"${thinking}\" is not supported by ${requested_model.provider}/${requested_model.id}; using \"${effective_thinking}\".`,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\t...(await createAgentSessionFromServices({\n\t\t\t\tservices,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: sessionStartEvent as any,\n\t\t\t\t...(requested_model ? { model: requested_model } : {}),\n\t\t\t\t...(effective_thinking\n\t\t\t\t\t? { thinkingLevel: effective_thinking }\n\t\t\t\t\t: {}),\n\t\t\t\t...(selected_tools?.length ? { tools: selected_tools } : {}),\n\t\t\t})),\n\t\t\tservices,\n\t\t\tdiagnostics: services.diagnostics,\n\t\t};\n\t};\n\n\ttry {\n\t\treturn wrap_runtime_env_restore(\n\t\t\tawait createAgentSessionRuntime(create_runtime, {\n\t\t\t\tcwd,\n\t\t\t\tagentDir: effective_agent_dir,\n\t\t\t\tsessionManager: SessionManager.create(\n\t\t\t\t\tcwd,\n\t\t\t\t\tsession_dir ? resolve(cwd, session_dir) : undefined,\n\t\t\t\t),\n\t\t\t}),\n\t\t\trestore_runtime_env,\n\t\t);\n\t} catch (error) {\n\t\trestore_runtime_env();\n\t\tthrow error;\n\t}\n}\n\nexport { InteractiveMode, runPrintMode, runRpcMode };\n\nexport type {\n\tAgentSessionRuntime,\n\tExtensionFactory,\n\tInteractiveModeOptions,\n\tPrintModeOptions,\n} from '@mariozechner/pi-coding-agent';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.js","names":[],"sources":["../src/extensions/manager/config.ts","../src/extensions/manager/index.ts","../src/api.ts"],"sourcesContent":["import {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\trenameSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport {\n\tBUILTIN_EXTENSIONS,\n\ttype BuiltinExtensionInfo,\n\ttype BuiltinExtensionKey,\n} from '../builtin-registry.js';\n\nexport { BUILTIN_EXTENSIONS };\nexport type { BuiltinExtensionInfo, BuiltinExtensionKey };\n\nexport interface BuiltinExtensionsConfig {\n\tversion: number;\n\tenabled: Partial<Record<BuiltinExtensionKey, boolean>>;\n}\n\nexport interface BuiltinExtensionState extends BuiltinExtensionInfo {\n\tsaved_enabled: boolean;\n\teffective_enabled: boolean;\n\tforced_disabled: boolean;\n}\n\nconst DEFAULT_CONFIG: BuiltinExtensionsConfig = {\n\tversion: 1,\n\tenabled: {},\n};\n\nexport function get_builtin_extensions_config_path(): string {\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn join(xdg, 'my-pi', 'extensions.json');\n}\n\nexport function load_builtin_extensions_config(): BuiltinExtensionsConfig {\n\tconst path = get_builtin_extensions_config_path();\n\tif (!existsSync(path)) return { ...DEFAULT_CONFIG };\n\n\ttry {\n\t\tconst raw = readFileSync(path, 'utf-8');\n\t\tconst parsed = JSON.parse(\n\t\t\traw,\n\t\t) as Partial<BuiltinExtensionsConfig>;\n\t\tconst enabled: BuiltinExtensionsConfig['enabled'] = {};\n\t\tfor (const extension of BUILTIN_EXTENSIONS) {\n\t\t\tconst value = parsed.enabled?.[extension.key];\n\t\t\tif (typeof value === 'boolean') {\n\t\t\t\tenabled[extension.key] = value;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tversion: parsed.version ?? 1,\n\t\t\tenabled,\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\nexport function save_builtin_extensions_config(\n\tconfig: BuiltinExtensionsConfig,\n): void {\n\tconst path = get_builtin_extensions_config_path();\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n\n\tconst tmp = `${path}.tmp-${Date.now()}`;\n\twriteFileSync(tmp, JSON.stringify(config, null, '\\t') + '\\n', {\n\t\tmode: 0o600,\n\t});\n\trenameSync(tmp, path);\n}\n\nexport function is_builtin_extension_enabled(\n\tconfig: BuiltinExtensionsConfig,\n\tkey: BuiltinExtensionKey,\n): boolean {\n\treturn config.enabled[key] ?? true;\n}\n\nexport function is_builtin_extension_active(\n\tconfig: BuiltinExtensionsConfig,\n\tkey: BuiltinExtensionKey,\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey> = new Set(),\n): boolean {\n\treturn (\n\t\tis_builtin_extension_enabled(config, key) &&\n\t\t!force_disabled.has(key)\n\t);\n}\n\nexport function resolve_builtin_extension_states(\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey> = new Set(),\n\tconfig: BuiltinExtensionsConfig = load_builtin_extensions_config(),\n): BuiltinExtensionState[] {\n\treturn BUILTIN_EXTENSIONS.map((extension) => {\n\t\tconst saved_enabled = is_builtin_extension_enabled(\n\t\t\tconfig,\n\t\t\textension.key,\n\t\t);\n\t\tconst forced = force_disabled.has(extension.key);\n\t\treturn {\n\t\t\t...extension,\n\t\t\tsaved_enabled,\n\t\t\teffective_enabled: saved_enabled && !forced,\n\t\t\tforced_disabled: forced,\n\t\t};\n\t});\n}\n\nexport function find_builtin_extension(\n\tquery: string,\n): BuiltinExtensionInfo | undefined {\n\tconst normalized = query.trim().toLowerCase();\n\tif (!normalized) return undefined;\n\n\treturn BUILTIN_EXTENSIONS.find((extension) =>\n\t\t[extension.key, extension.label, ...extension.aliases].some(\n\t\t\t(value) => value.toLowerCase() === normalized,\n\t\t),\n\t);\n}\n","import type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n} from '@earendil-works/pi-coding-agent';\nimport { type SettingItem } from '@earendil-works/pi-tui';\nimport { show_settings_modal } from '@spences10/pi-tui-modal';\nimport {\n\tBUILTIN_EXTENSIONS,\n\tfind_builtin_extension,\n\tload_builtin_extensions_config,\n\tresolve_builtin_extension_states,\n\tsave_builtin_extensions_config,\n\ttype BuiltinExtensionKey,\n\ttype BuiltinExtensionState,\n} from './config.js';\n\nconst ENABLED = '● enabled';\nconst DISABLED = '○ disabled';\n\nexport interface ExtensionsManagerOptions {\n\tforce_disabled?: Iterable<BuiltinExtensionKey>;\n}\n\nfunction to_force_disabled_set(\n\tforce_disabled?: Iterable<BuiltinExtensionKey>,\n): ReadonlySet<BuiltinExtensionKey> {\n\treturn new Set(force_disabled ?? []);\n}\n\nfunction format_effective_state(\n\tstate: BuiltinExtensionState,\n): string {\n\tif (state.effective_enabled) {\n\t\treturn 'enabled';\n\t}\n\tif (state.forced_disabled) {\n\t\treturn `disabled in this process by ${state.cli_flag}`;\n\t}\n\treturn 'disabled';\n}\n\nfunction format_extension_lines(\n\tstates: BuiltinExtensionState[],\n\toptions?: { heading?: string },\n): string {\n\tconst lines: string[] = [];\n\tif (options?.heading) {\n\t\tlines.push(options.heading, '');\n\t}\n\n\tconst enabled_now = states.filter(\n\t\t(state) => state.effective_enabled,\n\t).length;\n\tconst disabled_now = states.length - enabled_now;\n\tlines.push(\n\t\t`${states.length} built-in extensions (${enabled_now} enabled now, ${disabled_now} disabled now)`,\n\t\t'',\n\t);\n\n\tfor (const state of states) {\n\t\tlines.push(\n\t\t\t`${state.saved_enabled ? ENABLED : DISABLED} ${state.label}`,\n\t\t);\n\t\tlines.push(` key: ${state.key}`);\n\t\tlines.push(\n\t\t\t` saved config: ${state.saved_enabled ? 'enabled' : 'disabled'}`,\n\t\t);\n\t\tlines.push(\n\t\t\t` current process: ${format_effective_state(state)}`,\n\t\t);\n\t\tlines.push(` ${state.description}`);\n\t}\n\n\treturn lines.join('\\n');\n}\n\nfunction to_setting_item(state: BuiltinExtensionState): SettingItem {\n\tconst detail_lines = [\n\t\tstate.key,\n\t\tstate.description,\n\t\t`current process: ${format_effective_state(state)}`,\n\t\t`startup override: ${state.cli_flag}`,\n\t];\n\n\treturn {\n\t\tid: state.key,\n\t\tlabel: state.label,\n\t\tdescription: detail_lines.join('\\n'),\n\t\tcurrentValue: state.saved_enabled ? ENABLED : DISABLED,\n\t\tvalues: [ENABLED, DISABLED],\n\t};\n}\n\nfunction sets_equal(\n\ta: ReadonlySet<string>,\n\tb: ReadonlySet<string>,\n): boolean {\n\tif (a.size !== b.size) return false;\n\tfor (const value of a) {\n\t\tif (!b.has(value)) return false;\n\t}\n\treturn true;\n}\n\nfunction search_states(\n\tstates: BuiltinExtensionState[],\n\tquery: string,\n): BuiltinExtensionState[] {\n\tconst normalized = query.trim().toLowerCase();\n\tif (!normalized) return states;\n\n\treturn states.filter((state) =>\n\t\t[\n\t\t\tstate.key,\n\t\t\tstate.label,\n\t\t\tstate.description,\n\t\t\t...state.aliases,\n\t\t].some((value) => value.toLowerCase().includes(normalized)),\n\t);\n}\n\nfunction save_extension_enabled(\n\tkey: BuiltinExtensionKey,\n\tenabled: boolean,\n): void {\n\tconst config = load_builtin_extensions_config();\n\tconfig.enabled[key] = enabled;\n\tsave_builtin_extensions_config(config);\n}\n\nexport function create_extensions_extension(\n\toptions: ExtensionsManagerOptions = {},\n) {\n\tconst force_disabled = to_force_disabled_set(\n\t\toptions.force_disabled,\n\t);\n\n\tasync function show_manager(\n\t\tctx: ExtensionCommandContext,\n\t): Promise<boolean> {\n\t\tif (!ctx.hasUI) return false;\n\n\t\tconst states = resolve_builtin_extension_states(force_disabled);\n\t\tconst initial_enabled = new Set(\n\t\t\tstates\n\t\t\t\t.filter((state) => state.saved_enabled)\n\t\t\t\t.map((state) => state.key),\n\t\t);\n\t\tconst current_enabled = new Set(initial_enabled);\n\n\t\tconst items = states.map(to_setting_item);\n\t\tawait show_settings_modal(ctx, {\n\t\t\ttitle: 'Built-in extensions',\n\t\t\tsubtitle: () => {\n\t\t\t\tconst saved_enabled = current_enabled.size;\n\t\t\t\tconst saved_disabled = states.length - saved_enabled;\n\t\t\t\tconst enabled_now = [...current_enabled].filter(\n\t\t\t\t\t(key) => !force_disabled.has(key as BuiltinExtensionKey),\n\t\t\t\t).length;\n\t\t\t\tconst disabled_now = states.length - enabled_now;\n\t\t\t\treturn `${saved_enabled} saved enabled • ${saved_disabled} saved disabled • ${enabled_now} enabled now • ${disabled_now} disabled now`;\n\t\t\t},\n\t\t\titems,\n\t\t\tenable_search: true,\n\t\t\tfooter:\n\t\t\t\t'esc close • search filters • changes save immediately • CLI --no-* flags still win in this process',\n\t\t\ton_change: (id, new_value) => {\n\t\t\t\tconst key = id as BuiltinExtensionKey;\n\t\t\t\tconst enabled = new_value === ENABLED;\n\t\t\t\tif (enabled) {\n\t\t\t\t\tcurrent_enabled.add(key);\n\t\t\t\t} else {\n\t\t\t\t\tcurrent_enabled.delete(key);\n\t\t\t\t}\n\t\t\t\tsave_extension_enabled(key, enabled);\n\t\t\t},\n\t\t});\n\n\t\tif (!sets_equal(initial_enabled, current_enabled)) {\n\t\t\tctx.ui.notify(\n\t\t\t\tforce_disabled.size > 0\n\t\t\t\t\t? 'Reloading to apply updated built-in extensions. CLI --no-* flags still force-disable some extensions in this process.'\n\t\t\t\t\t: 'Reloading to apply updated built-in extensions...',\n\t\t\t\t'info',\n\t\t\t);\n\t\t\tawait ctx.reload();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\treturn async function extensions(pi: ExtensionAPI) {\n\t\tconst subs = ['list', 'enable', 'disable', 'toggle', 'search'];\n\n\t\tpi.registerCommand('extensions', {\n\t\t\tdescription: 'Manage built-in my-pi extensions',\n\t\t\tgetArgumentCompletions: (prefix) => {\n\t\t\t\tconst parts = prefix.trim().split(/\\s+/);\n\t\t\t\tif (parts.length <= 1) {\n\t\t\t\t\treturn subs\n\t\t\t\t\t\t.filter((sub) => sub.startsWith(parts[0] || ''))\n\t\t\t\t\t\t.map((sub) => ({ value: sub, label: sub }));\n\t\t\t\t}\n\n\t\t\t\tif (['enable', 'disable', 'toggle'].includes(parts[0])) {\n\t\t\t\t\tconst q = parts.slice(1).join(' ').toLowerCase();\n\t\t\t\t\treturn resolve_builtin_extension_states(force_disabled)\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(state) =>\n\t\t\t\t\t\t\t\tstate.key.toLowerCase().includes(q) ||\n\t\t\t\t\t\t\t\tstate.label.toLowerCase().includes(q),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.slice(0, 20)\n\t\t\t\t\t\t.map((state) => ({\n\t\t\t\t\t\t\tvalue: `${parts[0]} ${state.key}`,\n\t\t\t\t\t\t\tlabel: `${state.key} ${state.saved_enabled ? ENABLED : DISABLED}`,\n\t\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (await show_manager(ctx)) return;\n\t\t\t\t}\n\n\t\t\t\tconst [sub, ...rest] = (trimmed || 'list').split(/\\s+/);\n\t\t\t\tconst arg = rest.join(' ');\n\t\t\t\tconst states =\n\t\t\t\t\tresolve_builtin_extension_states(force_disabled);\n\n\t\t\t\tswitch (sub) {\n\t\t\t\t\tcase 'list': {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tformat_extension_lines(states, {\n\t\t\t\t\t\t\t\theading: 'Built-in extensions',\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'enable':\n\t\t\t\t\tcase 'disable':\n\t\t\t\t\tcase 'toggle': {\n\t\t\t\t\t\tif (!arg) {\n\t\t\t\t\t\t\tif (await show_manager(ctx)) return;\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`Usage: /extensions ${sub} <key>`,\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst extension = find_builtin_extension(arg);\n\t\t\t\t\t\tif (!extension) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`Unknown extension: ${arg}. Use: ${BUILTIN_EXTENSIONS.map((item) => item.key).join(', ')}`,\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst current_state = states.find(\n\t\t\t\t\t\t\t(state) => state.key === extension.key,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst next_enabled =\n\t\t\t\t\t\t\tsub === 'enable'\n\t\t\t\t\t\t\t\t? true\n\t\t\t\t\t\t\t\t: sub === 'disable'\n\t\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t\t: !current_state?.saved_enabled;\n\t\t\t\t\t\tsave_extension_enabled(extension.key, next_enabled);\n\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tnext_enabled && force_disabled.has(extension.key)\n\t\t\t\t\t\t\t\t? `Enabled ${extension.key} in saved config. Still disabled in this process by ${extension.cli_flag}. /reload or restart without that flag to apply.`\n\t\t\t\t\t\t\t\t: `${extension.key} ${next_enabled ? 'enabled' : 'disabled'}. /reload to apply.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'search': {\n\t\t\t\t\t\tif (!arg) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t'Usage: /extensions search <query>',\n\t\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst results = search_states(states, arg);\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`No built-in extensions matching \"${arg}\"`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tformat_extension_lines(results, {\n\t\t\t\t\t\t\t\theading: `Built-in extensions matching \"${arg}\"`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Unknown: ${sub}. Use: ${subs.join(', ')}`,\n\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t};\n}\n\nexport default create_extensions_extension();\n","// Composable programmatic API for my-pi\n// Extension loading patterns inspired by pi-vs-claude-code\n\nimport {\n\tclampThinkingLevel,\n\ttype Api,\n\ttype Model,\n} from '@earendil-works/pi-ai';\nimport {\n\tInteractiveMode,\n\tSessionManager,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionRuntime,\n\tcreateAgentSessionServices,\n\tgetAgentDir,\n\trunPrintMode,\n\trunRpcMode,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype ExtensionFactory,\n\ttype LoadExtensionsResult,\n} from '@earendil-works/pi-coding-agent';\nimport { apply_project_trust_untrusted_defaults } from '@spences10/pi-project-trust';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport {\n\tBUILTIN_EXTENSION_REGISTRY,\n\ttype BuiltinExtensionKey,\n\ttype BuiltinExtensionOptionName,\n} from './extensions/builtin-registry.js';\nimport {\n\tis_builtin_extension_active,\n\tload_builtin_extensions_config,\n} from './extensions/manager/config.js';\nimport { create_extensions_extension } from './extensions/manager/index.js';\n\nexport type MyPiRuntimeMode =\n\t| 'interactive'\n\t| 'print'\n\t| 'json'\n\t| 'rpc';\n\nexport type MyPiThinkingLevel = NonNullable<\n\tCreateAgentSessionFromServicesOptions['thinkingLevel']\n>;\n\ntype BuiltinExtensionOptions = Partial<\n\tRecord<BuiltinExtensionOptionName, boolean>\n>;\n\nexport interface CreateMyPiOptions extends BuiltinExtensionOptions {\n\tcwd?: string;\n\tagent_dir?: string;\n\textensions?: string[];\n\textensionFactories?: ExtensionFactory[];\n\truntime_mode?: MyPiRuntimeMode;\n\ttelemetry?: boolean;\n\ttelemetry_db_path?: string;\n\tmodel?: string;\n\tthinking?: MyPiThinkingLevel;\n\tselected_tools?: string[];\n\tselected_skills?: string[];\n\tsession_dir?: string;\n\tsystem_prompt?: string;\n\tappend_system_prompt?: string;\n\tuntrusted_repo?: boolean;\n}\n\ntype BuiltinExtensionLoader = () => Promise<ExtensionFactory>;\n\nconst require = createRequire(import.meta.url);\nconst PACKAGE_THEME_DIR = resolve(\n\tdirname(require.resolve('@spences10/pi-themes/package.json')),\n\t'themes',\n);\nconst PI_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nconst MY_PI_RUNTIME_MODE_ENV = 'MY_PI_RUNTIME_MODE';\n\ntype EnvSnapshot = Map<string, string | undefined>;\n\nfunction snapshot_env(\n\tenv: NodeJS.ProcessEnv,\n\tkeys: Iterable<string>,\n): EnvSnapshot {\n\treturn new Map(Array.from(keys, (key) => [key, env[key]]));\n}\n\nfunction restore_env(\n\tenv: NodeJS.ProcessEnv,\n\tsnapshot: EnvSnapshot,\n): void {\n\tfor (const [key, value] of snapshot) {\n\t\tif (value === undefined) delete env[key];\n\t\telse env[key] = value;\n\t}\n}\n\nfunction wrap_runtime_env_restore<\n\tT extends { dispose(): Promise<void> },\n>(runtime: T, restore: () => void): T {\n\tconst dispose = runtime.dispose.bind(runtime);\n\tlet restored = false;\n\tconst restore_once = () => {\n\t\tif (restored) return;\n\t\trestored = true;\n\t\trestore();\n\t};\n\n\truntime.dispose = (async () => {\n\t\ttry {\n\t\t\tawait dispose();\n\t\t} finally {\n\t\t\trestore_once();\n\t\t}\n\t}) as T['dispose'];\n\n\treturn runtime;\n}\n\nconst UNTRUSTED_CHILD_ENV_DEFAULTS: Record<string, string> = {\n\tMY_PI_CHILD_ENV_ALLOWLIST: '',\n\tMY_PI_MCP_ENV_ALLOWLIST: '',\n\tMY_PI_LSP_ENV_ALLOWLIST: '',\n\tMY_PI_HOOKS_ENV_ALLOWLIST: '',\n\tMY_PI_TEAM_MODE_ENV_ALLOWLIST: '',\n};\n\nexport function apply_untrusted_repo_defaults(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string[] {\n\tconst applied = apply_project_trust_untrusted_defaults(env);\n\tfor (const [key, value] of Object.entries(\n\t\tUNTRUSTED_CHILD_ENV_DEFAULTS,\n\t)) {\n\t\tif (env[key] !== undefined) continue;\n\t\tenv[key] = value;\n\t\tapplied.push(key);\n\t}\n\treturn applied;\n}\n\nfunction is_resource_enabled(value: string | undefined): boolean {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (!normalized) return true;\n\tif (['0', 'false', 'no', 'skip', 'disable'].includes(normalized)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction resolve_agent_dir(cwd: string, agent_dir?: string): string {\n\treturn agent_dir ? resolve(cwd, agent_dir) : getAgentDir();\n}\n\ninterface ModelRegistryLike {\n\tgetAll(): Model<Api>[];\n}\n\nexport function resolve_model_reference(\n\tmodel_reference: string | undefined,\n\tmodel_registry: ModelRegistryLike,\n): Model<Api> | undefined {\n\tif (!model_reference) return undefined;\n\tconst models = model_registry.getAll();\n\tconst lower_reference = model_reference.toLowerCase();\n\tconst slash_index = model_reference.indexOf('/');\n\n\tif (slash_index !== -1) {\n\t\tconst maybe_provider = model_reference.slice(0, slash_index);\n\t\tconst model_id = model_reference.slice(slash_index + 1);\n\t\tconst provider = models.find(\n\t\t\t(model) =>\n\t\t\t\tmodel.provider.toLowerCase() === maybe_provider.toLowerCase(),\n\t\t)?.provider;\n\n\t\tif (provider) {\n\t\t\tconst provider_match = models.find(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider === provider &&\n\t\t\t\t\tmodel.id.toLowerCase() === model_id.toLowerCase(),\n\t\t\t);\n\t\t\tif (provider_match) return provider_match;\n\t\t}\n\t}\n\n\treturn models.find((model) => {\n\t\tconst id = model.id.toLowerCase();\n\t\tconst full_id = `${model.provider}/${model.id}`.toLowerCase();\n\t\treturn id === lower_reference || full_id === lower_reference;\n\t});\n}\n\nexport function resolve_effective_thinking_level(\n\tmodel: Model<Api> | undefined,\n\tthinking: MyPiThinkingLevel | undefined,\n): MyPiThinkingLevel | undefined {\n\tif (!thinking || !model) return thinking;\n\treturn clampThinkingLevel(model, thinking);\n}\n\nexport function get_force_disabled_builtins(\n\toptions: Pick<CreateMyPiOptions, 'runtime_mode'> &\n\t\tBuiltinExtensionOptions,\n): ReadonlySet<BuiltinExtensionKey> {\n\tconst force_disabled = new Set<BuiltinExtensionKey>();\n\tfor (const extension of BUILTIN_EXTENSION_REGISTRY) {\n\t\tconst enabled =\n\t\t\toptions[extension.option_name] ?? extension.default_enabled;\n\t\tif (!enabled) force_disabled.add(extension.key);\n\t\tconst disabled_in =\n\t\t\t'mode_constraints' in extension\n\t\t\t\t? extension.mode_constraints.disabled_in\n\t\t\t\t: undefined;\n\t\tif (\n\t\t\toptions.runtime_mode &&\n\t\t\t(\n\t\t\t\tdisabled_in as readonly MyPiRuntimeMode[] | undefined\n\t\t\t)?.includes(options.runtime_mode)\n\t\t) {\n\t\t\tforce_disabled.add(extension.key);\n\t\t}\n\t}\n\treturn force_disabled;\n}\n\nexport function create_lazy_builtin_extension_factory(\n\tkey: BuiltinExtensionKey,\n\tload_extension: BuiltinExtensionLoader,\n\tforce_disabled: ReadonlySet<BuiltinExtensionKey>,\n): ExtensionFactory {\n\treturn async (pi) => {\n\t\tconst config = load_builtin_extensions_config();\n\t\tif (!is_builtin_extension_active(config, key, force_disabled)) {\n\t\t\treturn;\n\t\t}\n\t\tconst extension = await load_extension();\n\t\tawait extension(pi);\n\t};\n}\n\nfunction create_lazy_telemetry_extension(options: {\n\tenabled?: boolean;\n\tdb_path?: string;\n\tcwd?: string;\n}): ExtensionFactory {\n\treturn async (pi) => {\n\t\tconst { create_telemetry_extension } =\n\t\t\tawait import('@spences10/pi-telemetry');\n\t\tawait create_telemetry_extension(options)(pi);\n\t};\n}\n\nfunction create_extensions_override(\n\tmanaged_inline_paths: string[],\n): (base: LoadExtensionsResult) => LoadExtensionsResult {\n\tconst managed_paths = new Set(managed_inline_paths);\n\treturn (base) => {\n\t\tconst managed = new Map(\n\t\t\tbase.extensions.map((extension) => [extension.path, extension]),\n\t\t);\n\t\tconst ordered_managed = managed_inline_paths\n\t\t\t.map((path) => managed.get(path))\n\t\t\t.filter(\n\t\t\t\t(\n\t\t\t\t\textension,\n\t\t\t\t): extension is LoadExtensionsResult['extensions'][number] =>\n\t\t\t\t\tBoolean(extension),\n\t\t\t);\n\t\tconst others = base.extensions.filter(\n\t\t\t(extension) => !managed_paths.has(extension.path),\n\t\t);\n\t\treturn {\n\t\t\t...base,\n\t\t\textensions: [...ordered_managed, ...others],\n\t\t};\n\t};\n}\n\nexport async function create_my_pi(options: CreateMyPiOptions = {}) {\n\tconst {\n\t\tcwd = process.cwd(),\n\t\tagent_dir,\n\t\textensions = [],\n\t\textensionFactories: user_factories = [],\n\t\truntime_mode = 'interactive',\n\t\ttelemetry,\n\t\ttelemetry_db_path,\n\t\tmodel,\n\t\tthinking,\n\t\tselected_tools,\n\t\tselected_skills,\n\t\tsession_dir,\n\t\tsystem_prompt,\n\t\tappend_system_prompt,\n\t\tuntrusted_repo = false,\n\t} = options;\n\n\tconst env_keys_to_restore = new Set<string>([\n\t\tMY_PI_RUNTIME_MODE_ENV,\n\t]);\n\tif (agent_dir) env_keys_to_restore.add(PI_AGENT_DIR_ENV);\n\tconst env_snapshot = snapshot_env(process.env, env_keys_to_restore);\n\tlet restore_runtime_env = () =>\n\t\trestore_env(process.env, env_snapshot);\n\n\tif (untrusted_repo) {\n\t\tconst applied = apply_untrusted_repo_defaults();\n\t\tif (applied.length) {\n\t\t\tconst restore_previous = restore_runtime_env;\n\t\t\trestore_runtime_env = () => {\n\t\t\t\tfor (const key of applied) delete process.env[key];\n\t\t\t\trestore_previous();\n\t\t\t};\n\t\t}\n\t}\n\n\tconst effective_agent_dir = resolve_agent_dir(cwd, agent_dir);\n\tif (agent_dir) {\n\t\tprocess.env[PI_AGENT_DIR_ENV] = effective_agent_dir;\n\t}\n\tprocess.env[MY_PI_RUNTIME_MODE_ENV] = runtime_mode;\n\n\tconst resolved_extensions = extensions.map((p) => resolve(cwd, p));\n\tconst force_disabled = get_force_disabled_builtins({\n\t\t...options,\n\t\truntime_mode,\n\t});\n\tconst builtins_config = load_builtin_extensions_config();\n\tconst skills_builtin_enabled = is_builtin_extension_active(\n\t\tbuiltins_config,\n\t\t'skills',\n\t\tforce_disabled,\n\t);\n\tconst skills_package = skills_builtin_enabled\n\t\t? await import('@spences10/pi-skills')\n\t\t: undefined;\n\n\tconst managed_extension_factories: ExtensionFactory[] = [\n\t\tcreate_lazy_telemetry_extension({\n\t\t\tenabled: telemetry,\n\t\t\tdb_path: telemetry_db_path,\n\t\t\tcwd,\n\t\t}),\n\t\tcreate_extensions_extension({ force_disabled }),\n\t\t...BUILTIN_EXTENSION_REGISTRY.map((extension) =>\n\t\t\tcreate_lazy_builtin_extension_factory(\n\t\t\t\textension.key,\n\t\t\t\textension.load,\n\t\t\t\tforce_disabled,\n\t\t\t),\n\t\t),\n\t];\n\tconst managed_inline_paths = managed_extension_factories.map(\n\t\t(_, index) => `<inline:${index + 1}>`,\n\t);\n\n\tconst create_runtime = async ({\n\t\tcwd: runtime_cwd,\n\t\tsessionManager,\n\t\tsessionStartEvent,\n\t}: {\n\t\tcwd: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: unknown;\n\t}) => {\n\t\t// Keep skill filtering reloadable so profile changes made by\n\t\t// /skills are reflected without restarting the process.\n\t\tconst runtime_skills_manager =\n\t\t\tskills_package?.create_skills_manager({\n\t\t\t\tcwd: runtime_cwd,\n\t\t\t\tproject_skills_enabled: is_resource_enabled(\n\t\t\t\t\tprocess.env.MY_PI_PROJECT_SKILLS,\n\t\t\t\t),\n\t\t\t});\n\t\tconst additional_skill_paths =\n\t\t\truntime_skills_manager?.get_enabled_skill_paths() ?? [];\n\n\t\tconst services = await createAgentSessionServices({\n\t\t\tcwd: runtime_cwd,\n\t\t\tagentDir: effective_agent_dir,\n\t\t\tresourceLoaderOptions: {\n\t\t\t\t...(additional_skill_paths.length\n\t\t\t\t\t? { additionalSkillPaths: additional_skill_paths }\n\t\t\t\t\t: {}),\n\t\t\t\t...(system_prompt !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tsystemPromptOverride: () => system_prompt,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t...(append_system_prompt !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tappendSystemPromptOverride: (base: string[]) => [\n\t\t\t\t\t\t\t\t...base,\n\t\t\t\t\t\t\t\tappend_system_prompt,\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tadditionalExtensionPaths: [...resolved_extensions],\n\t\t\t\t...(runtime_mode === 'interactive'\n\t\t\t\t\t? { additionalThemePaths: [PACKAGE_THEME_DIR] }\n\t\t\t\t\t: {}),\n\t\t\t\textensionFactories: [\n\t\t\t\t\t...managed_extension_factories,\n\t\t\t\t\t...user_factories,\n\t\t\t\t],\n\t\t\t\textensionsOverride: create_extensions_override(\n\t\t\t\t\tmanaged_inline_paths,\n\t\t\t\t),\n\t\t\t\tskillsOverride: (base: any) => {\n\t\t\t\t\tif (!runtime_skills_manager) return base;\n\t\t\t\t\truntime_skills_manager.refresh();\n\n\t\t\t\t\tconst selected_skill_names = selected_skills?.length\n\t\t\t\t\t\t? new Set(selected_skills)\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...base,\n\t\t\t\t\t\tskills: base.skills.filter((skill: any) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tselected_skill_names &&\n\t\t\t\t\t\t\t\t!selected_skill_names.has(skill.name)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn runtime_skills_manager.is_enabled_by_skill(\n\t\t\t\t\t\t\t\tskill.name,\n\t\t\t\t\t\t\t\tskill.filePath,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t} as any,\n\t\t});\n\n\t\tconst requested_model = resolve_model_reference(\n\t\t\tmodel,\n\t\t\tservices.modelRegistry,\n\t\t);\n\t\tconst effective_thinking = resolve_effective_thinking_level(\n\t\t\trequested_model,\n\t\t\tthinking,\n\t\t);\n\t\tif (\n\t\t\trequested_model &&\n\t\t\tthinking &&\n\t\t\teffective_thinking &&\n\t\t\teffective_thinking !== thinking\n\t\t) {\n\t\t\tservices.diagnostics.push({\n\t\t\t\ttype: 'warning',\n\t\t\t\tmessage: `Requested thinking level \"${thinking}\" is not supported by ${requested_model.provider}/${requested_model.id}; using \"${effective_thinking}\".`,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\t...(await createAgentSessionFromServices({\n\t\t\t\tservices,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: sessionStartEvent as any,\n\t\t\t\t...(requested_model ? { model: requested_model } : {}),\n\t\t\t\t...(effective_thinking\n\t\t\t\t\t? { thinkingLevel: effective_thinking }\n\t\t\t\t\t: {}),\n\t\t\t\t...(selected_tools?.length ? { tools: selected_tools } : {}),\n\t\t\t})),\n\t\t\tservices,\n\t\t\tdiagnostics: services.diagnostics,\n\t\t};\n\t};\n\n\ttry {\n\t\treturn wrap_runtime_env_restore(\n\t\t\tawait createAgentSessionRuntime(create_runtime, {\n\t\t\t\tcwd,\n\t\t\t\tagentDir: effective_agent_dir,\n\t\t\t\tsessionManager: SessionManager.create(\n\t\t\t\t\tcwd,\n\t\t\t\t\tsession_dir ? resolve(cwd, session_dir) : undefined,\n\t\t\t\t),\n\t\t\t}),\n\t\t\trestore_runtime_env,\n\t\t);\n\t} catch (error) {\n\t\trestore_runtime_env();\n\t\tthrow error;\n\t}\n}\n\nexport { InteractiveMode, runPrintMode, runRpcMode };\n\nexport type {\n\tAgentSessionRuntime,\n\tExtensionFactory,\n\tInteractiveModeOptions,\n\tPrintModeOptions,\n} from '@earendil-works/pi-coding-agent';\n"],"mappings":"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"}
|
|
@@ -152,7 +152,7 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
152
152
|
],
|
|
153
153
|
reason: "Startup screen only renders in the interactive TUI"
|
|
154
154
|
},
|
|
155
|
-
load: async () => (await import("./startup-screen-
|
|
155
|
+
load: async () => (await import("./startup-screen-ofHxGDsk.js")).default
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
key: "prompt-presets",
|
|
@@ -169,7 +169,7 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
169
169
|
"preset",
|
|
170
170
|
"presets"
|
|
171
171
|
],
|
|
172
|
-
load: async () => (await import("./prompt-presets-
|
|
172
|
+
load: async () => (await import("./prompt-presets-Cl3vBbc-.js")).default
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
key: "lsp",
|
|
@@ -207,7 +207,7 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
207
207
|
],
|
|
208
208
|
reason: "UI-only session naming is only useful in interactive mode"
|
|
209
209
|
},
|
|
210
|
-
load: async () => (await import("./session-name-
|
|
210
|
+
load: async () => (await import("./session-name-8BLMnCqq.js")).default
|
|
211
211
|
},
|
|
212
212
|
{
|
|
213
213
|
key: "confirm-destructive",
|
|
@@ -226,14 +226,27 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
226
226
|
key: "hooks-resolution",
|
|
227
227
|
label: "Hooks resolution",
|
|
228
228
|
docs_label: "Hooks resolution",
|
|
229
|
-
description: "Claude Code style PostToolUse hook compatibility from .claude, .rulesync, and .pi configs",
|
|
229
|
+
description: "Claude Code style PreToolUse and PostToolUse hook compatibility from .claude, .rulesync, and .pi configs",
|
|
230
230
|
default_enabled: true,
|
|
231
231
|
option_name: "hooks_resolution",
|
|
232
232
|
cli_arg: "no-hooks",
|
|
233
233
|
cli_flag: "--no-hooks",
|
|
234
234
|
cli_description: "Disable Claude-style hook execution",
|
|
235
235
|
aliases: ["hooks-resolution", "hooks"],
|
|
236
|
-
load: async () => (await import("./hooks-resolution-
|
|
236
|
+
load: async () => (await import("./hooks-resolution-D89Ewkyw.js")).default
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
key: "svelte-guardrails",
|
|
240
|
+
label: "Svelte guardrails",
|
|
241
|
+
docs_label: "Svelte guardrails",
|
|
242
|
+
description: "Blocks discouraged Svelte patterns like $effect before agents write them",
|
|
243
|
+
default_enabled: true,
|
|
244
|
+
option_name: "svelte_guardrails",
|
|
245
|
+
cli_arg: "no-svelte-guardrails",
|
|
246
|
+
cli_flag: "--no-svelte-guardrails",
|
|
247
|
+
cli_description: "Disable Svelte guardrails",
|
|
248
|
+
aliases: ["svelte-guardrails", "svelte"],
|
|
249
|
+
load: async () => (await import("@spences10/pi-svelte-guardrails")).default
|
|
237
250
|
},
|
|
238
251
|
{
|
|
239
252
|
key: "team-mode",
|
|
@@ -257,4 +270,4 @@ const BUILTIN_EXTENSIONS = BUILTIN_EXTENSION_REGISTRY.map(({ load: _load, ...ext
|
|
|
257
270
|
//#endregion
|
|
258
271
|
export { BUILTIN_EXTENSION_REGISTRY as n, BUILTIN_EXTENSIONS as t };
|
|
259
272
|
|
|
260
|
-
//# sourceMappingURL=builtin-registry-
|
|
273
|
+
//# sourceMappingURL=builtin-registry-1hIf07ru.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-registry-1hIf07ru.js","names":[],"sources":["../src/extensions/builtin-registry.ts"],"sourcesContent":["import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nexport type BuiltinExtensionRuntimeMode =\n\t| 'interactive'\n\t| 'print'\n\t| 'json'\n\t| 'rpc';\n\ntype BuiltinExtensionLoader = () => Promise<ExtensionFactory>;\n\nexport interface BuiltinExtensionManifestEntry {\n\tkey: string;\n\tlabel: string;\n\tdocs_label: string;\n\tdescription: string;\n\tdefault_enabled: boolean;\n\toption_name: string;\n\tcli_arg: string;\n\tcli_flag: `--${string}`;\n\tcli_description: string;\n\taliases: readonly string[];\n\tmode_constraints?: {\n\t\tdisabled_in: readonly BuiltinExtensionRuntimeMode[];\n\t\treason: string;\n\t};\n\tload: BuiltinExtensionLoader;\n}\n\nexport const BUILTIN_EXTENSION_REGISTRY = [\n\t{\n\t\tkey: 'context-sidecar',\n\t\tlabel: 'Context sidecar',\n\t\tdocs_label: 'SQLite context sidecar',\n\t\tdescription: 'Local SQLite FTS sidecar for oversized tool output',\n\t\tdefault_enabled: true,\n\t\toption_name: 'context_sidecar',\n\t\tcli_arg: 'no-context-sidecar',\n\t\tcli_flag: '--no-context-sidecar',\n\t\tcli_description:\n\t\t\t'Disable SQLite context sidecar for large tool output',\n\t\taliases: ['context-sidecar', 'context', 'sidecar'],\n\t\tload: async () => (await import('@spences10/pi-context')).default,\n\t},\n\t{\n\t\tkey: 'mcp',\n\t\tlabel: 'MCP',\n\t\tdocs_label: 'MCP',\n\t\tdescription: 'MCP server integration and /mcp command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'mcp',\n\t\tcli_arg: 'no-mcp',\n\t\tcli_flag: '--no-mcp',\n\t\tcli_description: 'Disable built-in MCP extension',\n\t\taliases: ['mcp'],\n\t\tload: async () => (await import('@spences10/pi-mcp')).default,\n\t},\n\t{\n\t\tkey: 'skills',\n\t\tlabel: 'Skills',\n\t\tdocs_label: 'Skills',\n\t\tdescription: 'Managed pi-native skills and /skills command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skills',\n\t\tcli_arg: 'no-skills',\n\t\tcli_flag: '--no-skills',\n\t\tcli_description: 'Disable built-in skills extension',\n\t\taliases: ['skills', 'skill'],\n\t\tload: async () => (await import('@spences10/pi-skills')).default,\n\t},\n\t{\n\t\tkey: 'filter-output',\n\t\tlabel: 'Secret redaction',\n\t\tdocs_label: 'Secret redaction',\n\t\tdescription:\n\t\t\t'Redacts secrets from tool output before the model sees them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'filter_output',\n\t\tcli_arg: 'no-filter',\n\t\tcli_flag: '--no-filter',\n\t\tcli_description: 'Disable secret redaction in tool output',\n\t\taliases: [\n\t\t\t'filter-output',\n\t\t\t'filter_output',\n\t\t\t'filter',\n\t\t\t'redaction',\n\t\t\t'secret-redaction',\n\t\t\t'output-redaction',\n\t\t],\n\t\tload: async () => (await import('@spences10/pi-redact')).default,\n\t},\n\t{\n\t\tkey: 'recall',\n\t\tlabel: 'Recall',\n\t\tdocs_label: 'Recall',\n\t\tdescription: 'pirecall reminder and background session sync',\n\t\tdefault_enabled: true,\n\t\toption_name: 'recall',\n\t\tcli_arg: 'no-recall',\n\t\tcli_flag: '--no-recall',\n\t\tcli_description: 'Disable recall extension',\n\t\taliases: ['recall', 'pirecall'],\n\t\tload: async () => (await import('@spences10/pi-recall')).default,\n\t},\n\t{\n\t\tkey: 'nopeek',\n\t\tlabel: 'Nopeek',\n\t\tdocs_label: 'Nopeek',\n\t\tdescription:\n\t\t\t'nopeek reminder for secret-safe environment loading',\n\t\tdefault_enabled: true,\n\t\toption_name: 'nopeek',\n\t\tcli_arg: 'no-nopeek',\n\t\tcli_flag: '--no-nopeek',\n\t\tcli_description: 'Disable nopeek reminder extension',\n\t\taliases: ['nopeek', 'secrets', 'secret-loading'],\n\t\tload: async () => (await import('@spences10/pi-nopeek')).default,\n\t},\n\t{\n\t\tkey: 'omnisearch',\n\t\tlabel: 'Omnisearch',\n\t\tdocs_label: 'Omnisearch',\n\t\tdescription: 'mcp-omnisearch reminder for verified web research',\n\t\tdefault_enabled: true,\n\t\toption_name: 'omnisearch',\n\t\tcli_arg: 'no-omnisearch',\n\t\tcli_flag: '--no-omnisearch',\n\t\tcli_description: 'Disable mcp-omnisearch reminder extension',\n\t\taliases: ['omnisearch', 'search', 'web-search', 'research'],\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-omnisearch')).default,\n\t},\n\t{\n\t\tkey: 'sqlite-tools',\n\t\tlabel: 'SQLite tools',\n\t\tdocs_label: 'SQLite tools',\n\t\tdescription:\n\t\t\t'mcp-sqlite-tools reminder for safer SQLite database work',\n\t\tdefault_enabled: true,\n\t\toption_name: 'sqlite_tools',\n\t\tcli_arg: 'no-sqlite-tools',\n\t\tcli_flag: '--no-sqlite-tools',\n\t\tcli_description: 'Disable mcp-sqlite-tools reminder extension',\n\t\taliases: ['sqlite-tools', 'sqlite', 'mcp-sqlite-tools'],\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-sqlite-tools')).default,\n\t},\n\t{\n\t\tkey: 'startup-screen',\n\t\tlabel: 'Startup screen',\n\t\tdocs_label: 'Startup screen',\n\t\tdescription:\n\t\t\t'Pixel-art gradient startup header for interactive sessions',\n\t\tdefault_enabled: true,\n\t\toption_name: 'startup_screen',\n\t\tcli_arg: 'no-startup-screen',\n\t\tcli_flag: '--no-startup-screen',\n\t\tcli_description: 'Disable the custom startup screen',\n\t\taliases: ['startup-screen', 'startup', 'header', 'splash'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Startup screen only renders in the interactive TUI',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./startup-screen/index.js')).default,\n\t},\n\t{\n\t\tkey: 'prompt-presets',\n\t\tlabel: 'Prompt presets',\n\t\tdocs_label: 'Prompt presets',\n\t\tdescription:\n\t\t\t'Runtime prompt preset selection and /prompt-preset command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'prompt_presets',\n\t\tcli_arg: 'no-prompt-presets',\n\t\tcli_flag: '--no-prompt-presets',\n\t\tcli_description: 'Disable prompt presets extension',\n\t\taliases: ['prompt-preset', 'preset', 'presets'],\n\t\tload: async () =>\n\t\t\t(await import('./prompt-presets/index.js')).default,\n\t},\n\t{\n\t\tkey: 'lsp',\n\t\tlabel: 'LSP',\n\t\tdocs_label: 'LSP',\n\t\tdescription:\n\t\t\t'Language Server Protocol tools (diagnostics, hover, definition, references)',\n\t\tdefault_enabled: true,\n\t\toption_name: 'lsp',\n\t\tcli_arg: 'no-lsp',\n\t\tcli_flag: '--no-lsp',\n\t\tcli_description: 'Disable LSP extension',\n\t\taliases: ['lsp', 'language-server'],\n\t\tload: async () => (await import('@spences10/pi-lsp')).default,\n\t},\n\t{\n\t\tkey: 'session-name',\n\t\tlabel: 'Session name',\n\t\tdocs_label: 'Session auto-naming',\n\t\tdescription:\n\t\t\t'AI-powered session auto-naming and /session-name command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'session_name',\n\t\tcli_arg: 'no-session-name',\n\t\tcli_flag: '--no-session-name',\n\t\tcli_description: 'Disable session name extension',\n\t\taliases: ['session-name', 'session', 'auto-name'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason:\n\t\t\t\t'UI-only session naming is only useful in interactive mode',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./session-name/index.js')).default,\n\t},\n\t{\n\t\tkey: 'confirm-destructive',\n\t\tlabel: 'Confirm destructive',\n\t\tdocs_label: 'Destructive action confirmation',\n\t\tdescription:\n\t\t\t'Prompt before destructive tool calls like file deletes, overwrites, and hard resets',\n\t\tdefault_enabled: true,\n\t\toption_name: 'confirm_destructive',\n\t\tcli_arg: 'no-confirm-destructive',\n\t\tcli_flag: '--no-confirm-destructive',\n\t\tcli_description: 'Disable destructive action confirmations',\n\t\taliases: ['confirm-destructive', 'confirm'],\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-confirm-destructive')).default,\n\t},\n\t{\n\t\tkey: 'hooks-resolution',\n\t\tlabel: 'Hooks resolution',\n\t\tdocs_label: 'Hooks resolution',\n\t\tdescription:\n\t\t\t'Claude Code style PreToolUse and PostToolUse hook compatibility from .claude, .rulesync, and .pi configs',\n\t\tdefault_enabled: true,\n\t\toption_name: 'hooks_resolution',\n\t\tcli_arg: 'no-hooks',\n\t\tcli_flag: '--no-hooks',\n\t\tcli_description: 'Disable Claude-style hook execution',\n\t\taliases: ['hooks-resolution', 'hooks'],\n\t\tload: async () =>\n\t\t\t(await import('./hooks-resolution/index.js')).default,\n\t},\n\t{\n\t\tkey: 'svelte-guardrails',\n\t\tlabel: 'Svelte guardrails',\n\t\tdocs_label: 'Svelte guardrails',\n\t\tdescription:\n\t\t\t'Blocks discouraged Svelte patterns like $effect before agents write them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'svelte_guardrails',\n\t\tcli_arg: 'no-svelte-guardrails',\n\t\tcli_flag: '--no-svelte-guardrails',\n\t\tcli_description: 'Disable Svelte guardrails',\n\t\taliases: ['svelte-guardrails', 'svelte'],\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-svelte-guardrails')).default,\n\t},\n\t{\n\t\tkey: 'team-mode',\n\t\tlabel: 'Team mode',\n\t\tdocs_label: 'Team mode',\n\t\tdescription:\n\t\t\t'Experimental orchestrator/team mode with RPC teammates, tasks, and mailboxes',\n\t\tdefault_enabled: true,\n\t\toption_name: 'team_mode',\n\t\tcli_arg: 'no-team-mode',\n\t\tcli_flag: '--no-team-mode',\n\t\tcli_description: 'Disable experimental team mode extension',\n\t\taliases: ['team-mode', 'team', 'teammates'],\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-team-mode')).default,\n\t},\n] as const satisfies readonly BuiltinExtensionManifestEntry[];\n\nexport type BuiltinExtensionKey =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['key'];\n\nexport type BuiltinExtensionOptionName =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['option_name'];\n\nexport type BuiltinExtensionInfo = Omit<\n\tBuiltinExtensionManifestEntry,\n\t'load'\n> & {\n\tkey: BuiltinExtensionKey;\n\toption_name: BuiltinExtensionOptionName;\n};\n\nexport const BUILTIN_EXTENSIONS: BuiltinExtensionInfo[] =\n\tBUILTIN_EXTENSION_REGISTRY.map(\n\t\t({ load: _load, ...extension }) => extension,\n\t);\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
-
import { getAgentDir } from "@
|
|
3
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { is_project_subject_trusted, read_project_trust_store, resolve_project_trust } from "@spences10/pi-project-trust";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
@@ -108,7 +108,7 @@ function create_hook(event_name, matcher_text, command, source, project_dir) {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
function get_hook_entries(hooks_record, event_name) {
|
|
111
|
-
const keys = event_name === "PostToolUse" ? ["PostToolUse", "postToolUse"] : ["PostToolUseFailure", "postToolUseFailure"];
|
|
111
|
+
const keys = event_name === "PreToolUse" ? ["PreToolUse", "preToolUse"] : event_name === "PostToolUse" ? ["PostToolUse", "postToolUse"] : ["PostToolUseFailure", "postToolUseFailure"];
|
|
112
112
|
for (const key of keys) {
|
|
113
113
|
const value = hooks_record[key];
|
|
114
114
|
if (Array.isArray(value)) return value;
|
|
@@ -120,7 +120,11 @@ function parse_claude_settings_hooks(config, source, project_dir) {
|
|
|
120
120
|
const hooks_root = root ? as_record(root.hooks) : void 0;
|
|
121
121
|
if (!hooks_root) return [];
|
|
122
122
|
const hooks = [];
|
|
123
|
-
for (const event_name of [
|
|
123
|
+
for (const event_name of [
|
|
124
|
+
"PreToolUse",
|
|
125
|
+
"PostToolUse",
|
|
126
|
+
"PostToolUseFailure"
|
|
127
|
+
]) {
|
|
124
128
|
const entries = get_hook_entries(hooks_root, event_name);
|
|
125
129
|
for (const entry of entries) {
|
|
126
130
|
const entry_record = as_record(entry);
|
|
@@ -143,7 +147,11 @@ function parse_simple_hooks_file(config, source, project_dir) {
|
|
|
143
147
|
const hooks_root = root ? as_record(root.hooks) : void 0;
|
|
144
148
|
if (!hooks_root) return [];
|
|
145
149
|
const hooks = [];
|
|
146
|
-
for (const event_name of [
|
|
150
|
+
for (const event_name of [
|
|
151
|
+
"PreToolUse",
|
|
152
|
+
"PostToolUse",
|
|
153
|
+
"PostToolUseFailure"
|
|
154
|
+
]) {
|
|
147
155
|
const entries = get_hook_entries(hooks_root, event_name);
|
|
148
156
|
for (const entry of entries) {
|
|
149
157
|
const entry_record = as_record(entry);
|
|
@@ -247,16 +255,17 @@ function build_tool_response(event, normalized_input) {
|
|
|
247
255
|
}
|
|
248
256
|
function build_hook_payload(event, event_name, ctx, project_dir) {
|
|
249
257
|
const normalized_input = normalize_tool_input(event.input);
|
|
250
|
-
|
|
258
|
+
const payload = {
|
|
251
259
|
session_id: ctx.sessionManager.getSessionFile() ?? "ephemeral",
|
|
252
260
|
cwd: ctx.cwd,
|
|
253
261
|
claude_project_dir: project_dir,
|
|
254
262
|
hook_event_name: event_name,
|
|
255
263
|
tool_name: to_claude_tool_name(event.toolName),
|
|
256
264
|
tool_call_id: event.toolCallId,
|
|
257
|
-
tool_input: normalized_input
|
|
258
|
-
tool_response: build_tool_response(event, normalized_input)
|
|
265
|
+
tool_input: normalized_input
|
|
259
266
|
};
|
|
267
|
+
if ("content" in event) payload.tool_response = build_tool_response(event, normalized_input);
|
|
268
|
+
return payload;
|
|
260
269
|
}
|
|
261
270
|
async function run_command_hook(command, cwd, payload) {
|
|
262
271
|
return await new Promise((resolve) => {
|
|
@@ -319,6 +328,20 @@ async function run_command_hook(command, cwd, payload) {
|
|
|
319
328
|
function hook_event_name_for_result(event) {
|
|
320
329
|
return event.isError ? "PostToolUseFailure" : "PostToolUse";
|
|
321
330
|
}
|
|
331
|
+
function hook_block_reason(result) {
|
|
332
|
+
const parse_json = (text) => {
|
|
333
|
+
const trimmed = text.trim();
|
|
334
|
+
if (!trimmed) return void 0;
|
|
335
|
+
try {
|
|
336
|
+
return as_record(JSON.parse(trimmed));
|
|
337
|
+
} catch {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
const json = parse_json(result.stdout) ?? parse_json(result.stderr);
|
|
342
|
+
if (json?.decision === "block") return typeof json.reason === "string" ? json.reason : "Blocked by hook";
|
|
343
|
+
if (result.code === 2) return result.stderr.trim() || result.stdout.trim() || "Blocked by hook";
|
|
344
|
+
}
|
|
322
345
|
function format_duration(elapsed_ms) {
|
|
323
346
|
if (elapsed_ms < 1e3) return `${elapsed_ms}ms`;
|
|
324
347
|
return `${(elapsed_ms / 1e3).toFixed(1)}s`;
|
|
@@ -390,6 +413,22 @@ function create_hooks_resolution_extension(options = {}) {
|
|
|
390
413
|
pi.on("session_start", async (_event, ctx) => {
|
|
391
414
|
await refresh_hooks(ctx.cwd, ctx);
|
|
392
415
|
});
|
|
416
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
417
|
+
if (state.hooks.length === 0) return;
|
|
418
|
+
const matching_hooks = state.hooks.filter((hook) => hook.event_name === "PreToolUse" && matches_hook(hook, event.toolName));
|
|
419
|
+
if (matching_hooks.length === 0) return;
|
|
420
|
+
const payload = build_hook_payload(event, "PreToolUse", ctx, state.project_dir);
|
|
421
|
+
const executed_commands = /* @__PURE__ */ new Set();
|
|
422
|
+
for (const hook of matching_hooks) {
|
|
423
|
+
if (executed_commands.has(hook.command)) continue;
|
|
424
|
+
executed_commands.add(hook.command);
|
|
425
|
+
const reason = hook_block_reason(await run_command_hook_impl(hook.command, state.project_dir, payload));
|
|
426
|
+
if (reason) return {
|
|
427
|
+
block: true,
|
|
428
|
+
reason
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
});
|
|
393
432
|
pi.on("tool_result", async (event, ctx) => {
|
|
394
433
|
if (state.hooks.length === 0) return;
|
|
395
434
|
const event_name = hook_event_name_for_result(event);
|
|
@@ -416,4 +455,4 @@ var hooks_resolution_default = create_hooks_resolution_extension();
|
|
|
416
455
|
//#endregion
|
|
417
456
|
export { hooks_resolution_default as default };
|
|
418
457
|
|
|
419
|
-
//# sourceMappingURL=hooks-resolution-
|
|
458
|
+
//# sourceMappingURL=hooks-resolution-D89Ewkyw.js.map
|