my-pi 0.1.21 → 0.1.22
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 +23 -4
- package/dist/{api-SEiGG2V_.js → api-ByzD9jne.js} +37 -101
- package/dist/api-ByzD9jne.js.map +1 -0
- package/dist/api.js +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/package.json +14 -13
- package/src/extensions/manager/index.ts +30 -87
- package/src/extensions/prompt-presets/index.ts +31 -98
- package/dist/api-SEiGG2V_.js.map +0 -1
- package/themes/catppuccin-mocha.json +0 -79
- package/themes/dracula.json +0 -78
- package/themes/gruvbox-dark.json +0 -78
- package/themes/night-owl.json +0 -78
- package/themes/nord.json +0 -78
- package/themes/one-dark.json +0 -78
- package/themes/rose-pine.json +0 -78
- package/themes/solarized-dark.json +0 -79
- package/themes/tokyo-night.json +0 -78
package/README.md
CHANGED
|
@@ -276,9 +276,10 @@ still force-disable those extensions for the current process only.
|
|
|
276
276
|
|
|
277
277
|
### Themes
|
|
278
278
|
|
|
279
|
-
`my-pi`
|
|
280
|
-
the runtime automatically.
|
|
281
|
-
|
|
279
|
+
`my-pi` bundles `@spences10/pi-themes` and loads that theme pack into
|
|
280
|
+
the runtime automatically. Vanilla Pi users can install it separately
|
|
281
|
+
with `pi install npm:@spences10/pi-themes`. Pick a theme in
|
|
282
|
+
`/settings`, or persist one via Pi settings JSON:
|
|
282
283
|
|
|
283
284
|
```json
|
|
284
285
|
{
|
|
@@ -381,6 +382,12 @@ and headless sessions skip it unless `MY_PI_MCP_PROJECT_CONFIG=allow`
|
|
|
381
382
|
or `MY_PI_MCP_PROJECT_CONFIG=trust` is set. If both configs define the
|
|
382
383
|
same server name, the trusted project config wins.
|
|
383
384
|
|
|
385
|
+
Use `/mcp` in interactive mode to open the searchable MCP server
|
|
386
|
+
modal. Enter/Space toggles servers on or off, updates the active tool
|
|
387
|
+
set, and persists the choice as `disabled`/`enabled` in `mcp.json`.
|
|
388
|
+
Use `/mcp backup`, `/mcp restore`, and `/mcp profile ...` to back up,
|
|
389
|
+
restore, save, and load reusable MCP server sets.
|
|
390
|
+
|
|
384
391
|
### Hooks
|
|
385
392
|
|
|
386
393
|
Claude-style hooks are discovered from `.claude/settings.json`,
|
|
@@ -582,7 +589,11 @@ session start and shutdown when the local recall database exists.
|
|
|
582
589
|
|
|
583
590
|
This repo is a pnpm workspace. The `my-pi` harness depends on reusable
|
|
584
591
|
Pi packages via `workspace:*`, and those packages can also be
|
|
585
|
-
published and installed into vanilla `pi` independently
|
|
592
|
+
published and installed into vanilla `pi` independently. Shared helper
|
|
593
|
+
packages such as `@spences10/pi-child-env`,
|
|
594
|
+
`@spences10/pi-project-trust`, and `@spences10/pi-tui-modal` are
|
|
595
|
+
published only as dependencies and are not Pi packages to install via
|
|
596
|
+
`pi install`.
|
|
586
597
|
|
|
587
598
|
```bash
|
|
588
599
|
pi install npm:@spences10/pi-redact
|
|
@@ -596,6 +607,7 @@ pi install npm:@spences10/pi-nopeek
|
|
|
596
607
|
pi install npm:@spences10/pi-omnisearch
|
|
597
608
|
pi install npm:@spences10/pi-sqlite-tools
|
|
598
609
|
pi install npm:@spences10/pi-team-mode
|
|
610
|
+
pi install npm:@spences10/pi-themes
|
|
599
611
|
```
|
|
600
612
|
|
|
601
613
|
- [`@spences10/pi-redact`](./packages/pi-redact/README.md) — output
|
|
@@ -621,6 +633,8 @@ pi install npm:@spences10/pi-team-mode
|
|
|
621
633
|
- [`@spences10/pi-team-mode`](./packages/pi-team-mode/README.md) —
|
|
622
634
|
local orchestrator/team mode with RPC teammates, tasks, and
|
|
623
635
|
mailboxes
|
|
636
|
+
- [`@spences10/pi-themes`](./packages/pi-themes/README.md) — bundled
|
|
637
|
+
theme pack for Pi
|
|
624
638
|
|
|
625
639
|
Each package README is the entry point for install instructions,
|
|
626
640
|
commands, runtime behavior, and development notes.
|
|
@@ -647,6 +661,11 @@ packages/
|
|
|
647
661
|
pi-nopeek/ Installable Pi package for nopeek reminders
|
|
648
662
|
pi-omnisearch/ Installable Pi package for mcp-omnisearch reminders
|
|
649
663
|
pi-sqlite-tools/ Installable Pi package for mcp-sqlite-tools reminders
|
|
664
|
+
pi-team-mode/ Installable Pi package for team orchestration
|
|
665
|
+
pi-themes/ Installable Pi theme pack
|
|
666
|
+
pi-child-env/ Shared support package, not a Pi package
|
|
667
|
+
pi-project-trust/ Shared support package, not a Pi package
|
|
668
|
+
pi-tui-modal/ Shared support package, not a Pi package
|
|
650
669
|
.pi/
|
|
651
670
|
presets.json Optional project prompt presets (JSON)
|
|
652
671
|
presets/*.md Optional project prompt presets (Markdown files)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { BorderedLoader, InteractiveMode as InteractiveMode$1, SessionManager, convertToLlm, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, runPrintMode as runPrintMode$1, runRpcMode as runRpcMode$1, serializeConversation } from "@mariozechner/pi-coding-agent";
|
|
2
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
5
|
import confirm_destructive_extension from "@spences10/pi-confirm-destructive";
|
|
6
6
|
import lsp_extension from "@spences10/pi-lsp";
|
|
7
7
|
import mcp_extension from "@spences10/pi-mcp";
|
|
@@ -18,7 +18,8 @@ import { spawn } from "node:child_process";
|
|
|
18
18
|
import { createHash } from "node:crypto";
|
|
19
19
|
import { create_child_process_env } from "@spences10/pi-child-env";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
|
-
import {
|
|
21
|
+
import { show_settings_modal } from "@spences10/pi-tui-modal";
|
|
22
|
+
import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
|
|
22
23
|
import { complete } from "@mariozechner/pi-ai";
|
|
23
24
|
//#region src/extensions/hooks-resolution/env.ts
|
|
24
25
|
function create_child_process_env$1(explicit_env = {}, source_env = process.env) {
|
|
@@ -620,8 +621,8 @@ function find_builtin_extension(query) {
|
|
|
620
621
|
}
|
|
621
622
|
//#endregion
|
|
622
623
|
//#region src/extensions/manager/index.ts
|
|
623
|
-
const ENABLED$1 = "
|
|
624
|
-
const DISABLED$1 = "
|
|
624
|
+
const ENABLED$1 = "● enabled";
|
|
625
|
+
const DISABLED$1 = "○ disabled";
|
|
625
626
|
function to_force_disabled_set(force_disabled) {
|
|
626
627
|
return new Set(force_disabled ?? []);
|
|
627
628
|
}
|
|
@@ -687,54 +688,24 @@ function create_extensions_extension(options = {}) {
|
|
|
687
688
|
const states = resolve_builtin_extension_states(force_disabled);
|
|
688
689
|
const initial_enabled = new Set(states.filter((state) => state.saved_enabled).map((state) => state.key));
|
|
689
690
|
const current_enabled = new Set(initial_enabled);
|
|
690
|
-
await ctx
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
""
|
|
703
|
-
];
|
|
704
|
-
},
|
|
705
|
-
invalidate: () => {}
|
|
706
|
-
});
|
|
707
|
-
const settings_list = new SettingsList(items, Math.min(Math.max(items.length + 4, 8), 16), {
|
|
708
|
-
cursor: theme.fg("accent", "›"),
|
|
709
|
-
label: (text, selected) => selected ? theme.fg("accent", text) : text,
|
|
710
|
-
value: (text, selected) => {
|
|
711
|
-
const color = text === ENABLED$1 ? "success" : "dim";
|
|
712
|
-
const rendered = theme.fg(color, text);
|
|
713
|
-
return selected ? theme.bold(theme.fg("accent", rendered)) : rendered;
|
|
714
|
-
},
|
|
715
|
-
description: (text) => theme.fg("muted", text),
|
|
716
|
-
hint: (text) => theme.fg("dim", text)
|
|
717
|
-
}, (id, new_value) => {
|
|
691
|
+
await show_settings_modal(ctx, {
|
|
692
|
+
title: "Built-in extensions",
|
|
693
|
+
subtitle: () => {
|
|
694
|
+
const saved_enabled = current_enabled.size;
|
|
695
|
+
const saved_disabled = states.length - saved_enabled;
|
|
696
|
+
const enabled_now = [...current_enabled].filter((key) => !force_disabled.has(key)).length;
|
|
697
|
+
return `${saved_enabled} saved enabled • ${saved_disabled} saved disabled • ${enabled_now} enabled now • ${states.length - enabled_now} disabled now`;
|
|
698
|
+
},
|
|
699
|
+
items: states.map(to_setting_item),
|
|
700
|
+
enable_search: true,
|
|
701
|
+
footer: "esc close • search filters • changes save immediately • CLI --no-* flags still win in this process",
|
|
702
|
+
on_change: (id, new_value) => {
|
|
718
703
|
const key = id;
|
|
719
704
|
const enabled = new_value === ENABLED$1;
|
|
720
705
|
if (enabled) current_enabled.add(key);
|
|
721
706
|
else current_enabled.delete(key);
|
|
722
707
|
save_extension_enabled(key, enabled);
|
|
723
|
-
}
|
|
724
|
-
container.addChild(settings_list);
|
|
725
|
-
container.addChild(new Text(theme.fg("dim", "esc close • search filters • changes save immediately • CLI --no-* flags still win in this process"), 0, 1));
|
|
726
|
-
return {
|
|
727
|
-
render(width) {
|
|
728
|
-
return container.render(width);
|
|
729
|
-
},
|
|
730
|
-
invalidate() {
|
|
731
|
-
container.invalidate();
|
|
732
|
-
},
|
|
733
|
-
handleInput(data) {
|
|
734
|
-
settings_list.handleInput(data);
|
|
735
|
-
tui.requestRender();
|
|
736
|
-
}
|
|
737
|
-
};
|
|
708
|
+
}
|
|
738
709
|
});
|
|
739
710
|
if (!sets_equal$1(initial_enabled, current_enabled)) {
|
|
740
711
|
ctx.ui.notify(force_disabled.size > 0 ? "Reloading to apply updated built-in extensions. CLI --no-* flags still force-disable some extensions in this process." : "Reloading to apply updated built-in extensions...", "info");
|
|
@@ -826,10 +797,10 @@ create_extensions_extension();
|
|
|
826
797
|
//#region src/extensions/prompt-presets/index.ts
|
|
827
798
|
const PROJECT_PROMPT_PRESETS_ENV = "MY_PI_PROMPT_PRESETS_PROJECT";
|
|
828
799
|
const PRESET_STATE_TYPE = "prompt-preset-state";
|
|
829
|
-
const ENABLED = "
|
|
830
|
-
const DISABLED = "
|
|
831
|
-
const SELECTED = "
|
|
832
|
-
const UNSELECTED = "
|
|
800
|
+
const ENABLED = "● enabled";
|
|
801
|
+
const DISABLED = "○ disabled";
|
|
802
|
+
const SELECTED = "● selected";
|
|
803
|
+
const UNSELECTED = "○";
|
|
833
804
|
const NONE_BASE_ID = "__base_none__";
|
|
834
805
|
const DEFAULT_PROMPT_PRESETS = {
|
|
835
806
|
terse: {
|
|
@@ -1549,21 +1520,13 @@ async function prompt_presets(pi) {
|
|
|
1549
1520
|
else if (layer_ids.has(item.id)) item.currentValue = enabled_layers.has(item.id) ? ENABLED : DISABLED;
|
|
1550
1521
|
}
|
|
1551
1522
|
sync_values();
|
|
1552
|
-
await ctx
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
value: (text, selected) => {
|
|
1560
|
-
const color = text === ENABLED || text === SELECTED ? "success" : "dim";
|
|
1561
|
-
const rendered = theme.fg(color, text);
|
|
1562
|
-
return selected ? theme.bold(theme.fg("accent", rendered)) : rendered;
|
|
1563
|
-
},
|
|
1564
|
-
description: (text) => theme.fg("muted", text),
|
|
1565
|
-
hint: (text) => theme.fg("dim", text)
|
|
1566
|
-
}, (id, new_value) => {
|
|
1523
|
+
await show_settings_modal(ctx, {
|
|
1524
|
+
title: "Prompt presets",
|
|
1525
|
+
subtitle: () => `base: ${selected_base ?? "(none)"} • ${enabled_layers.size} layer(s) enabled`,
|
|
1526
|
+
items,
|
|
1527
|
+
max_visible: Math.min(Math.max(items.length + 4, 8), 24),
|
|
1528
|
+
enable_search: true,
|
|
1529
|
+
on_change: (id, new_value) => {
|
|
1567
1530
|
if (id.startsWith("__header_")) return;
|
|
1568
1531
|
if (base_ids.has(id)) {
|
|
1569
1532
|
selected_base = new_value === SELECTED && id !== NONE_BASE_ID ? id : void 0;
|
|
@@ -1575,37 +1538,7 @@ async function prompt_presets(pi) {
|
|
|
1575
1538
|
else enabled_layers.delete(id);
|
|
1576
1539
|
sync_values();
|
|
1577
1540
|
}
|
|
1578
|
-
}
|
|
1579
|
-
const container = new Container();
|
|
1580
|
-
container.addChild({
|
|
1581
|
-
render: () => [
|
|
1582
|
-
theme.fg("accent", theme.bold("Prompt presets")),
|
|
1583
|
-
theme.fg("muted", `base: ${selected_base ?? "(none)"} • ${enabled_layers.size} layer(s) enabled`),
|
|
1584
|
-
""
|
|
1585
|
-
],
|
|
1586
|
-
invalidate: () => {}
|
|
1587
|
-
});
|
|
1588
|
-
container.addChild({
|
|
1589
|
-
render(width) {
|
|
1590
|
-
return list.render(width);
|
|
1591
|
-
},
|
|
1592
|
-
invalidate() {
|
|
1593
|
-
list.invalidate();
|
|
1594
|
-
}
|
|
1595
|
-
});
|
|
1596
|
-
container.addChild(new Text(theme.fg("dim", "search filters • enter toggles • esc close"), 0, 1));
|
|
1597
|
-
return {
|
|
1598
|
-
render(width) {
|
|
1599
|
-
return container.render(width);
|
|
1600
|
-
},
|
|
1601
|
-
invalidate() {
|
|
1602
|
-
container.invalidate();
|
|
1603
|
-
},
|
|
1604
|
-
handleInput(data) {
|
|
1605
|
-
list.handleInput(data);
|
|
1606
|
-
tui.requestRender();
|
|
1607
|
-
}
|
|
1608
|
-
};
|
|
1541
|
+
}
|
|
1609
1542
|
});
|
|
1610
1543
|
if (selected_base !== initial_base || !sets_equal(initial_layers, enabled_layers)) commit_state(ctx, selected_base, enabled_layers, { notify: "Updated prompt preset selection" });
|
|
1611
1544
|
}
|
|
@@ -1971,7 +1904,7 @@ const BUILTIN_EXTENSION_FACTORIES = {
|
|
|
1971
1904
|
"hooks-resolution": hooks_resolution_default,
|
|
1972
1905
|
"team-mode": team_mode_extension
|
|
1973
1906
|
};
|
|
1974
|
-
const PACKAGE_THEME_DIR = resolve(dirname(
|
|
1907
|
+
const PACKAGE_THEME_DIR = resolve(dirname(createRequire(import.meta.url).resolve("@spences10/pi-themes/package.json")), "themes");
|
|
1975
1908
|
const PI_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
|
|
1976
1909
|
const UNTRUSTED_CHILD_ENV_DEFAULTS = {
|
|
1977
1910
|
MY_PI_CHILD_ENV_ALLOWLIST: "",
|
|
@@ -2069,7 +2002,7 @@ function create_extensions_override(managed_inline_paths) {
|
|
|
2069
2002
|
};
|
|
2070
2003
|
}
|
|
2071
2004
|
async function create_my_pi(options = {}) {
|
|
2072
|
-
const { cwd = process.cwd(), agent_dir, extensions = [], extensionFactories: user_factories = [], runtime_mode = "interactive", mcp = true, skills = true, filter_output = true, recall = true, nopeek = true, omnisearch = true, sqlite_tools = true, prompt_presets = true, lsp = true, session_name = true, confirm_destructive = true, hooks_resolution = true, team_mode = true, telemetry, telemetry_db_path, model, session_dir, system_prompt, append_system_prompt, untrusted_repo = false } = options;
|
|
2005
|
+
const { cwd = process.cwd(), agent_dir, extensions = [], extensionFactories: user_factories = [], runtime_mode = "interactive", mcp = true, skills = true, filter_output = true, recall = true, nopeek = true, omnisearch = true, sqlite_tools = true, prompt_presets = true, lsp = true, session_name = true, confirm_destructive = true, hooks_resolution = true, team_mode = true, telemetry, telemetry_db_path, model, selected_tools, selected_skills, session_dir, system_prompt, append_system_prompt, untrusted_repo = false } = options;
|
|
2073
2006
|
if (untrusted_repo) apply_untrusted_repo_defaults();
|
|
2074
2007
|
const effective_agent_dir = resolve_agent_dir(cwd, agent_dir);
|
|
2075
2008
|
if (agent_dir) process.env[PI_AGENT_DIR_ENV] = effective_agent_dir;
|
|
@@ -2115,10 +2048,12 @@ async function create_my_pi(options = {}) {
|
|
|
2115
2048
|
if (!is_builtin_extension_active(load_builtin_extensions_config(), "skills", force_disabled)) return base;
|
|
2116
2049
|
const include_project_skills = is_resource_enabled(process.env.MY_PI_PROJECT_SKILLS);
|
|
2117
2050
|
const skills_manager = create_skills_manager();
|
|
2051
|
+
const selected_skill_names = selected_skills?.length ? new Set(selected_skills) : void 0;
|
|
2118
2052
|
return {
|
|
2119
2053
|
...base,
|
|
2120
2054
|
skills: base.skills.filter((skill) => {
|
|
2121
2055
|
if (!include_project_skills && is_project_local_skill_path(runtime_cwd, skill.filePath)) return false;
|
|
2056
|
+
if (selected_skill_names && !selected_skill_names.has(skill.name)) return false;
|
|
2122
2057
|
return skills_manager.is_enabled_by_skill(skill.name, skill.filePath);
|
|
2123
2058
|
})
|
|
2124
2059
|
};
|
|
@@ -2131,7 +2066,8 @@ async function create_my_pi(options = {}) {
|
|
|
2131
2066
|
services,
|
|
2132
2067
|
sessionManager,
|
|
2133
2068
|
sessionStartEvent,
|
|
2134
|
-
...requested_model ? { model: requested_model } : {}
|
|
2069
|
+
...requested_model ? { model: requested_model } : {},
|
|
2070
|
+
...selected_tools?.length ? { tools: selected_tools } : {}
|
|
2135
2071
|
}),
|
|
2136
2072
|
services,
|
|
2137
2073
|
diagnostics: services.diagnostics
|
|
@@ -2146,4 +2082,4 @@ async function create_my_pi(options = {}) {
|
|
|
2146
2082
|
//#endregion
|
|
2147
2083
|
export { is_project_local_skill_path as a, runRpcMode$1 as c, get_force_disabled_builtins as i, apply_untrusted_repo_defaults as n, resolve_model_reference as o, create_my_pi as r, runPrintMode$1 as s, InteractiveMode$1 as t };
|
|
2148
2084
|
|
|
2149
|
-
//# sourceMappingURL=api-
|
|
2085
|
+
//# sourceMappingURL=api-ByzD9jne.js.map
|