my-pi 0.1.1 → 0.1.2
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/dist/{api-Dxi4curf.js → api-BVS4nqfD.js} +288 -42
- package/dist/api-BVS4nqfD.js.map +1 -0
- package/dist/api.js +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/extensions/chain.test.ts +25 -0
- package/src/extensions/chain.ts +10 -1
- package/src/extensions/config.test.ts +3 -0
- package/src/extensions/config.ts +10 -1
- package/src/extensions/mcp.test.ts +30 -0
- package/src/extensions/mcp.ts +151 -23
- package/src/extensions/prompt-presets.test.ts +53 -0
- package/src/extensions/prompt-presets.ts +53 -21
- package/src/extensions/recall.test.ts +26 -0
- package/src/extensions/recall.ts +13 -2
- package/src/extensions/telemetry.test.ts +18 -0
- package/src/extensions/telemetry.ts +12 -2
- package/src/extensions/working-indicator-config.test.ts +68 -0
- package/src/extensions/working-indicator-config.ts +81 -0
- package/src/extensions/working-indicator.test.ts +38 -0
- package/src/extensions/working-indicator.ts +155 -0
- package/dist/api-Dxi4curf.js.map +0 -1
|
@@ -60,6 +60,10 @@ function parse_chain_yaml(raw) {
|
|
|
60
60
|
if (current && current_step) current.steps.push(current_step);
|
|
61
61
|
return chains;
|
|
62
62
|
}
|
|
63
|
+
function should_inject_chain_prompt(event) {
|
|
64
|
+
const selected_tools = event.systemPromptOptions?.selectedTools;
|
|
65
|
+
return !selected_tools || selected_tools.includes("run_chain");
|
|
66
|
+
}
|
|
63
67
|
function parse_agent_file(filePath) {
|
|
64
68
|
try {
|
|
65
69
|
const { frontmatter, body } = parseFrontmatter(readFileSync(filePath, "utf-8"));
|
|
@@ -290,6 +294,7 @@ async function chain(pi) {
|
|
|
290
294
|
});
|
|
291
295
|
pi.on("before_agent_start", async (event) => {
|
|
292
296
|
if (!active_chain || chains.length === 0) return {};
|
|
297
|
+
if (!should_inject_chain_prompt(event)) return {};
|
|
293
298
|
const flow = active_chain.steps.map((s) => s.agent).join(" -> ");
|
|
294
299
|
const step_list = active_chain.steps.map((s, i) => {
|
|
295
300
|
const desc = agents.get(s.agent.toLowerCase())?.description || "unknown";
|
|
@@ -340,7 +345,7 @@ Switch chains with /chain <name>.` };
|
|
|
340
345
|
}
|
|
341
346
|
//#endregion
|
|
342
347
|
//#region src/extensions/config.ts
|
|
343
|
-
const DEFAULT_CONFIG$
|
|
348
|
+
const DEFAULT_CONFIG$3 = {
|
|
344
349
|
version: 1,
|
|
345
350
|
enabled: {}
|
|
346
351
|
};
|
|
@@ -434,6 +439,17 @@ const BUILTIN_EXTENSIONS = [
|
|
|
434
439
|
description: "Claude Code style PostToolUse hook compatibility from .claude, .rulesync, and .pi configs",
|
|
435
440
|
cli_flag: "--no-hooks",
|
|
436
441
|
aliases: ["hooks-resolution", "hooks"]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
key: "working-indicator",
|
|
445
|
+
label: "Working indicator",
|
|
446
|
+
description: "Customizable streaming working indicator with /working-indicator command",
|
|
447
|
+
cli_flag: "--no-working-indicator",
|
|
448
|
+
aliases: [
|
|
449
|
+
"working-indicator",
|
|
450
|
+
"indicator",
|
|
451
|
+
"spinner"
|
|
452
|
+
]
|
|
437
453
|
}
|
|
438
454
|
];
|
|
439
455
|
function get_builtin_extensions_config_path() {
|
|
@@ -441,7 +457,7 @@ function get_builtin_extensions_config_path() {
|
|
|
441
457
|
}
|
|
442
458
|
function load_builtin_extensions_config() {
|
|
443
459
|
const path = get_builtin_extensions_config_path();
|
|
444
|
-
if (!existsSync(path)) return { ...DEFAULT_CONFIG$
|
|
460
|
+
if (!existsSync(path)) return { ...DEFAULT_CONFIG$3 };
|
|
445
461
|
try {
|
|
446
462
|
const raw = readFileSync(path, "utf-8");
|
|
447
463
|
const parsed = JSON.parse(raw);
|
|
@@ -455,7 +471,7 @@ function load_builtin_extensions_config() {
|
|
|
455
471
|
enabled
|
|
456
472
|
};
|
|
457
473
|
} catch {
|
|
458
|
-
return { ...DEFAULT_CONFIG$
|
|
474
|
+
return { ...DEFAULT_CONFIG$3 };
|
|
459
475
|
}
|
|
460
476
|
}
|
|
461
477
|
function save_builtin_extensions_config(config) {
|
|
@@ -2515,6 +2531,14 @@ function load_mcp_config(cwd) {
|
|
|
2515
2531
|
}
|
|
2516
2532
|
//#endregion
|
|
2517
2533
|
//#region src/extensions/mcp.ts
|
|
2534
|
+
function create_server_states(configs) {
|
|
2535
|
+
return new Map(configs.map((config) => [config.name, {
|
|
2536
|
+
config,
|
|
2537
|
+
tool_names: [],
|
|
2538
|
+
enabled: true,
|
|
2539
|
+
status: "disconnected"
|
|
2540
|
+
}]));
|
|
2541
|
+
}
|
|
2518
2542
|
function remove_server_tools_from_active(pi, tool_names) {
|
|
2519
2543
|
const tool_set = new Set(tool_names);
|
|
2520
2544
|
pi.setActiveTools(pi.getActiveTools().filter((tool) => !tool_set.has(tool)));
|
|
@@ -2527,16 +2551,56 @@ function format_server_status(state) {
|
|
|
2527
2551
|
default: return state.enabled ? "not connected yet" : "disabled";
|
|
2528
2552
|
}
|
|
2529
2553
|
}
|
|
2554
|
+
function count_pending_enabled_servers(servers) {
|
|
2555
|
+
return Array.from(servers.values()).filter((state) => state.enabled && state.status !== "connected").length;
|
|
2556
|
+
}
|
|
2557
|
+
function update_mcp_status(ctx, servers) {
|
|
2558
|
+
if (servers.size === 0) {
|
|
2559
|
+
ctx.ui.setStatus("mcp", void 0);
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
const states = Array.from(servers.values());
|
|
2563
|
+
const enabled = states.filter((state) => state.enabled).length;
|
|
2564
|
+
const connected = states.filter((state) => state.enabled && state.status === "connected").length;
|
|
2565
|
+
const connecting = states.filter((state) => state.enabled && state.status === "connecting").length;
|
|
2566
|
+
const failed = states.filter((state) => state.enabled && state.status === "failed").length;
|
|
2567
|
+
const fragments = [`MCP ${connected}/${enabled} connected`];
|
|
2568
|
+
if (connecting > 0) fragments.push(`${connecting} connecting`);
|
|
2569
|
+
if (failed > 0) fragments.push(`${failed} failed`);
|
|
2570
|
+
ctx.ui.setStatus("mcp", ctx.ui.theme.fg("dim", fragments.join(" · ")));
|
|
2571
|
+
}
|
|
2572
|
+
function set_connect_feedback(ctx, pending_server_count) {
|
|
2573
|
+
const label = pending_server_count === 1 ? "Connecting 1 MCP server..." : `Connecting ${pending_server_count} MCP servers...`;
|
|
2574
|
+
ctx.ui.setWorkingMessage(label);
|
|
2575
|
+
ctx.ui.setWorkingIndicator({
|
|
2576
|
+
frames: [
|
|
2577
|
+
ctx.ui.theme.fg("dim", "·"),
|
|
2578
|
+
ctx.ui.theme.fg("muted", "•"),
|
|
2579
|
+
ctx.ui.theme.fg("accent", "●"),
|
|
2580
|
+
ctx.ui.theme.fg("muted", "•")
|
|
2581
|
+
],
|
|
2582
|
+
intervalMs: 120
|
|
2583
|
+
});
|
|
2584
|
+
ctx.ui.setStatus("mcp", ctx.ui.theme.fg("dim", label));
|
|
2585
|
+
return () => {
|
|
2586
|
+
ctx.ui.setWorkingMessage();
|
|
2587
|
+
ctx.ui.setWorkingIndicator();
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2590
|
+
function should_wait_for_mcp_connections(event) {
|
|
2591
|
+
const selected_tools = event.systemPromptOptions?.selectedTools;
|
|
2592
|
+
return !selected_tools || selected_tools.some((tool) => tool.startsWith("mcp__"));
|
|
2593
|
+
}
|
|
2530
2594
|
async function mcp(pi) {
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
config,
|
|
2534
|
-
tool_names: [],
|
|
2535
|
-
enabled: true,
|
|
2536
|
-
status: "disconnected"
|
|
2537
|
-
}]));
|
|
2595
|
+
let initialized_cwd = null;
|
|
2596
|
+
let servers = /* @__PURE__ */ new Map();
|
|
2538
2597
|
const registered_tool_names = /* @__PURE__ */ new Set();
|
|
2539
|
-
const
|
|
2598
|
+
const ensure_servers = (cwd) => {
|
|
2599
|
+
if (initialized_cwd !== null) return;
|
|
2600
|
+
servers = create_server_states(load_mcp_config(cwd));
|
|
2601
|
+
initialized_cwd = cwd;
|
|
2602
|
+
};
|
|
2603
|
+
const connect_server = async (state, ctx) => {
|
|
2540
2604
|
if (state.status === "connected") return;
|
|
2541
2605
|
if (state.connect_promise) {
|
|
2542
2606
|
await state.connect_promise;
|
|
@@ -2545,6 +2609,7 @@ async function mcp(pi) {
|
|
|
2545
2609
|
state.connect_promise = (async () => {
|
|
2546
2610
|
state.status = "connecting";
|
|
2547
2611
|
state.error = void 0;
|
|
2612
|
+
if (ctx) update_mcp_status(ctx, servers);
|
|
2548
2613
|
const client = new McpClient(state.config);
|
|
2549
2614
|
try {
|
|
2550
2615
|
await client.connect();
|
|
@@ -2588,19 +2653,39 @@ async function mcp(pi) {
|
|
|
2588
2653
|
throw error;
|
|
2589
2654
|
} finally {
|
|
2590
2655
|
state.connect_promise = void 0;
|
|
2656
|
+
if (ctx) update_mcp_status(ctx, servers);
|
|
2591
2657
|
}
|
|
2592
2658
|
})();
|
|
2593
2659
|
await state.connect_promise;
|
|
2594
2660
|
};
|
|
2595
2661
|
const connect_all_servers = async (options = {}) => {
|
|
2596
|
-
await Promise.allSettled(Array.from(servers.values()).filter((state) => state.enabled).filter((state) => options.include_failed || state.status !== "failed").map((state) => connect_server(state)));
|
|
2662
|
+
await Promise.allSettled(Array.from(servers.values()).filter((state) => state.enabled).filter((state) => options.include_failed || state.status !== "failed").map((state) => connect_server(state, options.ctx)));
|
|
2663
|
+
if (options.ctx) update_mcp_status(options.ctx, servers);
|
|
2597
2664
|
};
|
|
2598
|
-
pi.on("session_start", async () => {
|
|
2599
|
-
|
|
2665
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
2666
|
+
ensure_servers(ctx.cwd);
|
|
2667
|
+
update_mcp_status(ctx, servers);
|
|
2668
|
+
connect_all_servers({ ctx });
|
|
2600
2669
|
});
|
|
2601
|
-
pi.on("before_agent_start", async (event) => {
|
|
2602
|
-
|
|
2603
|
-
|
|
2670
|
+
pi.on("before_agent_start", async (event, ctx) => {
|
|
2671
|
+
ensure_servers(ctx.cwd);
|
|
2672
|
+
if (!should_wait_for_mcp_connections(event)) {
|
|
2673
|
+
connect_all_servers({ ctx });
|
|
2674
|
+
return event;
|
|
2675
|
+
}
|
|
2676
|
+
const pending_server_count = count_pending_enabled_servers(servers);
|
|
2677
|
+
if (pending_server_count === 0) {
|
|
2678
|
+
update_mcp_status(ctx, servers);
|
|
2679
|
+
return event;
|
|
2680
|
+
}
|
|
2681
|
+
const restore_feedback = set_connect_feedback(ctx, pending_server_count);
|
|
2682
|
+
try {
|
|
2683
|
+
await connect_all_servers({ ctx });
|
|
2684
|
+
return event;
|
|
2685
|
+
} finally {
|
|
2686
|
+
restore_feedback();
|
|
2687
|
+
update_mcp_status(ctx, servers);
|
|
2688
|
+
}
|
|
2604
2689
|
});
|
|
2605
2690
|
pi.registerCommand("mcp", {
|
|
2606
2691
|
description: "Manage MCP servers (list, enable, disable)",
|
|
@@ -2624,6 +2709,7 @@ async function mcp(pi) {
|
|
|
2624
2709
|
return null;
|
|
2625
2710
|
},
|
|
2626
2711
|
handler: async (args, ctx) => {
|
|
2712
|
+
ensure_servers(ctx.cwd);
|
|
2627
2713
|
const [sub, ...rest] = args.trim().split(/\s+/);
|
|
2628
2714
|
const name = rest.join(" ");
|
|
2629
2715
|
switch (sub || "list") {
|
|
@@ -2634,6 +2720,7 @@ async function mcp(pi) {
|
|
|
2634
2720
|
}
|
|
2635
2721
|
const lines = [];
|
|
2636
2722
|
for (const [sname, state] of servers.entries()) lines.push(`${sname} (${format_server_status(state)}) — ${state.tool_names.length} tools${state.error ? ` — ${state.error}` : ""}`);
|
|
2723
|
+
update_mcp_status(ctx, servers);
|
|
2637
2724
|
ctx.ui.notify(lines.join("\n"));
|
|
2638
2725
|
break;
|
|
2639
2726
|
}
|
|
@@ -2650,7 +2737,8 @@ async function mcp(pi) {
|
|
|
2650
2737
|
server.enabled = true;
|
|
2651
2738
|
if (server.status === "connected") {
|
|
2652
2739
|
const active = pi.getActiveTools();
|
|
2653
|
-
pi.setActiveTools([...active, ...server.tool_names]);
|
|
2740
|
+
pi.setActiveTools([...new Set([...active, ...server.tool_names])]);
|
|
2741
|
+
update_mcp_status(ctx, servers);
|
|
2654
2742
|
ctx.ui.notify(`Enabled ${name}`);
|
|
2655
2743
|
return;
|
|
2656
2744
|
}
|
|
@@ -2658,7 +2746,8 @@ async function mcp(pi) {
|
|
|
2658
2746
|
server.status = "disconnected";
|
|
2659
2747
|
server.error = void 0;
|
|
2660
2748
|
}
|
|
2661
|
-
|
|
2749
|
+
update_mcp_status(ctx, servers);
|
|
2750
|
+
connect_server(server, ctx);
|
|
2662
2751
|
ctx.ui.notify(`Enabling ${name} and connecting in background`);
|
|
2663
2752
|
break;
|
|
2664
2753
|
}
|
|
@@ -2674,6 +2763,7 @@ async function mcp(pi) {
|
|
|
2674
2763
|
}
|
|
2675
2764
|
server.enabled = false;
|
|
2676
2765
|
remove_server_tools_from_active(pi, server.tool_names);
|
|
2766
|
+
update_mcp_status(ctx, servers);
|
|
2677
2767
|
ctx.ui.notify(`Disabled ${name}`);
|
|
2678
2768
|
break;
|
|
2679
2769
|
}
|
|
@@ -2681,13 +2771,14 @@ async function mcp(pi) {
|
|
|
2681
2771
|
}
|
|
2682
2772
|
}
|
|
2683
2773
|
});
|
|
2684
|
-
pi.on("session_shutdown", async () => {
|
|
2774
|
+
pi.on("session_shutdown", async (_event, ctx) => {
|
|
2685
2775
|
await Promise.allSettled(Array.from(servers.values()).map(async (server) => {
|
|
2686
2776
|
await server.connect_promise?.catch(() => {});
|
|
2687
2777
|
await server.client?.disconnect();
|
|
2688
2778
|
server.client = void 0;
|
|
2689
2779
|
if (server.status !== "failed") server.status = "disconnected";
|
|
2690
2780
|
}));
|
|
2781
|
+
ctx.ui.setStatus("mcp", void 0);
|
|
2691
2782
|
});
|
|
2692
2783
|
}
|
|
2693
2784
|
//#endregion
|
|
@@ -2959,6 +3050,24 @@ function format_token_count(count) {
|
|
|
2959
3050
|
if (count < 1e7) return `${(count / 1e6).toFixed(1)}M`;
|
|
2960
3051
|
return `${Math.round(count / 1e6)}M`;
|
|
2961
3052
|
}
|
|
3053
|
+
function render_footer_status_line(theme, width, left_items, right_item) {
|
|
3054
|
+
const left = sanitize_status_text(left_items.join(" "));
|
|
3055
|
+
const right = right_item ? sanitize_status_text(right_item) : "";
|
|
3056
|
+
if (!left && !right) return void 0;
|
|
3057
|
+
if (!right) return truncateToWidth(theme.fg("dim", left), width, theme.fg("dim", "..."));
|
|
3058
|
+
if (!left) {
|
|
3059
|
+
const themed_right = theme.fg("dim", right);
|
|
3060
|
+
const right_width = visibleWidth(themed_right);
|
|
3061
|
+
return right_width >= width ? truncateToWidth(themed_right, width, theme.fg("dim", "...")) : `${" ".repeat(width - right_width)}${themed_right}`;
|
|
3062
|
+
}
|
|
3063
|
+
const right_width = visibleWidth(right);
|
|
3064
|
+
if (right_width >= width) return truncateToWidth(theme.fg("dim", right), width, theme.fg("dim", "..."));
|
|
3065
|
+
const min_gap = 1;
|
|
3066
|
+
const truncated_left = truncateToWidth(left, Math.max(0, width - right_width - min_gap), "...");
|
|
3067
|
+
const left_width = visibleWidth(truncated_left);
|
|
3068
|
+
const gap = Math.max(min_gap, width - left_width - right_width);
|
|
3069
|
+
return theme.fg("dim", truncated_left) + " ".repeat(gap) + theme.fg("dim", right);
|
|
3070
|
+
}
|
|
2962
3071
|
function get_current_thinking_level(ctx) {
|
|
2963
3072
|
const entries = ctx.sessionManager.getEntries();
|
|
2964
3073
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
@@ -3038,14 +3147,8 @@ function render_footer_lines(ctx, theme, footer_data, width, active_base_name, a
|
|
|
3038
3147
|
const dim_remainder = theme.fg("dim", remainder);
|
|
3039
3148
|
const lines = [truncateToWidth(theme.fg("dim", pwd), width, theme.fg("dim", "...")), dim_stats_left + dim_remainder];
|
|
3040
3149
|
const prompt_status = get_footer_prompt_status(active_base_name, active_layers);
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
const status_width = visibleWidth(themed_status);
|
|
3044
|
-
const aligned_status = status_width >= width ? truncateToWidth(themed_status, width, theme.fg("dim", "...")) : `${" ".repeat(width - status_width)}${themed_status}`;
|
|
3045
|
-
lines.push(aligned_status);
|
|
3046
|
-
}
|
|
3047
|
-
const other_statuses = Array.from(footer_data.getExtensionStatuses().entries()).filter(([key]) => key !== "preset").sort(([a], [b]) => a.localeCompare(b)).map(([, text]) => sanitize_status_text(text));
|
|
3048
|
-
if (other_statuses.length > 0) lines.push(truncateToWidth(other_statuses.join(" "), width, theme.fg("dim", "...")));
|
|
3150
|
+
const combined_status_line = render_footer_status_line(theme, width, Array.from(footer_data.getExtensionStatuses().entries()).filter(([key]) => key !== "preset").sort(([a], [b]) => a.localeCompare(b)).map(([, text]) => sanitize_status_text(text)), prompt_status);
|
|
3151
|
+
if (combined_status_line) lines.push(combined_status_line);
|
|
3049
3152
|
return lines;
|
|
3050
3153
|
}
|
|
3051
3154
|
function set_status(ctx, active_base_name, active_layers) {
|
|
@@ -3508,6 +3611,10 @@ async function prompt_presets(pi) {
|
|
|
3508
3611
|
//#endregion
|
|
3509
3612
|
//#region src/extensions/recall.ts
|
|
3510
3613
|
const DEFAULT_DB_PATH = join(process.env.HOME, ".pi", "pirecall.db");
|
|
3614
|
+
function should_inject_recall_prompt(event) {
|
|
3615
|
+
const selected_tools = event.systemPromptOptions?.selectedTools;
|
|
3616
|
+
return !selected_tools || selected_tools.includes("bash");
|
|
3617
|
+
}
|
|
3511
3618
|
function sync_recall_db_in_background() {
|
|
3512
3619
|
if (!existsSync(DEFAULT_DB_PATH)) return;
|
|
3513
3620
|
try {
|
|
@@ -3523,6 +3630,7 @@ async function recall(pi) {
|
|
|
3523
3630
|
sync_recall_db_in_background();
|
|
3524
3631
|
});
|
|
3525
3632
|
pi.on("before_agent_start", async (event) => {
|
|
3633
|
+
if (!should_inject_recall_prompt(event)) return {};
|
|
3526
3634
|
return { systemPrompt: event.systemPrompt + `
|
|
3527
3635
|
|
|
3528
3636
|
## Session Recall
|
|
@@ -3661,7 +3769,7 @@ async function session_name(pi) {
|
|
|
3661
3769
|
}
|
|
3662
3770
|
//#endregion
|
|
3663
3771
|
//#region src/skills/config.ts
|
|
3664
|
-
const DEFAULT_CONFIG$
|
|
3772
|
+
const DEFAULT_CONFIG$2 = {
|
|
3665
3773
|
version: 1,
|
|
3666
3774
|
enabled: {},
|
|
3667
3775
|
defaults: "all-disabled"
|
|
@@ -3671,7 +3779,7 @@ function get_config_path() {
|
|
|
3671
3779
|
}
|
|
3672
3780
|
function load_skills_config() {
|
|
3673
3781
|
const path = get_config_path();
|
|
3674
|
-
if (!existsSync(path)) return { ...DEFAULT_CONFIG$
|
|
3782
|
+
if (!existsSync(path)) return { ...DEFAULT_CONFIG$2 };
|
|
3675
3783
|
try {
|
|
3676
3784
|
const raw = readFileSync(path, "utf-8");
|
|
3677
3785
|
const parsed = JSON.parse(raw);
|
|
@@ -3681,7 +3789,7 @@ function load_skills_config() {
|
|
|
3681
3789
|
defaults: parsed.defaults ?? "all-enabled"
|
|
3682
3790
|
};
|
|
3683
3791
|
} catch {
|
|
3684
|
-
return { ...DEFAULT_CONFIG$
|
|
3792
|
+
return { ...DEFAULT_CONFIG$2 };
|
|
3685
3793
|
}
|
|
3686
3794
|
}
|
|
3687
3795
|
function save_skills_config(config) {
|
|
@@ -4408,7 +4516,7 @@ async function skills(pi) {
|
|
|
4408
4516
|
}
|
|
4409
4517
|
//#endregion
|
|
4410
4518
|
//#region src/extensions/telemetry-config.ts
|
|
4411
|
-
const DEFAULT_CONFIG = {
|
|
4519
|
+
const DEFAULT_CONFIG$1 = {
|
|
4412
4520
|
version: 1,
|
|
4413
4521
|
enabled: false
|
|
4414
4522
|
};
|
|
@@ -4424,15 +4532,15 @@ function resolve_telemetry_db_path(cwd, override_path) {
|
|
|
4424
4532
|
}
|
|
4425
4533
|
function load_telemetry_config() {
|
|
4426
4534
|
const path = get_telemetry_config_path();
|
|
4427
|
-
if (!existsSync(path)) return { ...DEFAULT_CONFIG };
|
|
4535
|
+
if (!existsSync(path)) return { ...DEFAULT_CONFIG$1 };
|
|
4428
4536
|
try {
|
|
4429
4537
|
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
4430
4538
|
return {
|
|
4431
|
-
version: typeof parsed.version === "number" ? parsed.version : DEFAULT_CONFIG.version,
|
|
4432
|
-
enabled: typeof parsed.enabled === "boolean" ? parsed.enabled : DEFAULT_CONFIG.enabled
|
|
4539
|
+
version: typeof parsed.version === "number" ? parsed.version : DEFAULT_CONFIG$1.version,
|
|
4540
|
+
enabled: typeof parsed.enabled === "boolean" ? parsed.enabled : DEFAULT_CONFIG$1.enabled
|
|
4433
4541
|
};
|
|
4434
4542
|
} catch {
|
|
4435
|
-
return { ...DEFAULT_CONFIG };
|
|
4543
|
+
return { ...DEFAULT_CONFIG$1 };
|
|
4436
4544
|
}
|
|
4437
4545
|
}
|
|
4438
4546
|
function save_telemetry_config(config) {
|
|
@@ -4591,6 +4699,10 @@ function infer_run_outcome(event) {
|
|
|
4591
4699
|
error_message: null
|
|
4592
4700
|
};
|
|
4593
4701
|
}
|
|
4702
|
+
function describe_session_shutdown(event) {
|
|
4703
|
+
const base = `session shutdown (${event.reason})`;
|
|
4704
|
+
return event.targetSessionFile ? `${base} → ${event.targetSessionFile}` : base;
|
|
4705
|
+
}
|
|
4594
4706
|
function format_telemetry_status(options) {
|
|
4595
4707
|
const override_label = options.override === void 0 ? "none" : options.override ? "--telemetry" : "--no-telemetry";
|
|
4596
4708
|
return [
|
|
@@ -4983,12 +5095,12 @@ function create_telemetry_extension(options = {}) {
|
|
|
4983
5095
|
headers_json: summarize_headers(event.headers)
|
|
4984
5096
|
});
|
|
4985
5097
|
});
|
|
4986
|
-
pi.on("session_shutdown", async () => {
|
|
5098
|
+
pi.on("session_shutdown", async (event) => {
|
|
4987
5099
|
if (store && active_run) store.finish_run({
|
|
4988
5100
|
id: active_run.id,
|
|
4989
5101
|
ended_at: now(),
|
|
4990
5102
|
success: null,
|
|
4991
|
-
error_message:
|
|
5103
|
+
error_message: describe_session_shutdown(event)
|
|
4992
5104
|
});
|
|
4993
5105
|
close_store();
|
|
4994
5106
|
active_run = null;
|
|
@@ -4999,6 +5111,137 @@ function create_telemetry_extension(options = {}) {
|
|
|
4999
5111
|
}
|
|
5000
5112
|
create_telemetry_extension();
|
|
5001
5113
|
//#endregion
|
|
5114
|
+
//#region src/extensions/working-indicator-config.ts
|
|
5115
|
+
const DEFAULT_CONFIG = {
|
|
5116
|
+
version: 1,
|
|
5117
|
+
mode: "spinner"
|
|
5118
|
+
};
|
|
5119
|
+
function get_working_indicator_config_path() {
|
|
5120
|
+
return join(getAgentDir(), "working-indicator.json");
|
|
5121
|
+
}
|
|
5122
|
+
function load_working_indicator_config() {
|
|
5123
|
+
const path = get_working_indicator_config_path();
|
|
5124
|
+
if (!existsSync(path)) return { ...DEFAULT_CONFIG };
|
|
5125
|
+
try {
|
|
5126
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
5127
|
+
return {
|
|
5128
|
+
version: typeof parsed.version === "number" ? parsed.version : DEFAULT_CONFIG.version,
|
|
5129
|
+
mode: is_working_indicator_mode(parsed.mode) ? parsed.mode : DEFAULT_CONFIG.mode
|
|
5130
|
+
};
|
|
5131
|
+
} catch {
|
|
5132
|
+
return { ...DEFAULT_CONFIG };
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
function save_working_indicator_config(config) {
|
|
5136
|
+
const path = get_working_indicator_config_path();
|
|
5137
|
+
const dir = dirname(path);
|
|
5138
|
+
if (!existsSync(dir)) mkdirSync(dir, {
|
|
5139
|
+
recursive: true,
|
|
5140
|
+
mode: 448
|
|
5141
|
+
});
|
|
5142
|
+
const tmp = `${path}.tmp-${Date.now()}`;
|
|
5143
|
+
writeFileSync(tmp, JSON.stringify(config, null, " ") + "\n", { mode: 384 });
|
|
5144
|
+
renameSync(tmp, path);
|
|
5145
|
+
}
|
|
5146
|
+
function is_working_indicator_mode(value) {
|
|
5147
|
+
return value === "default" || value === "dot" || value === "none" || value === "pulse" || value === "spinner";
|
|
5148
|
+
}
|
|
5149
|
+
//#endregion
|
|
5150
|
+
//#region src/extensions/working-indicator.ts
|
|
5151
|
+
const COMMAND_MODES = [
|
|
5152
|
+
"dot",
|
|
5153
|
+
"none",
|
|
5154
|
+
"pulse",
|
|
5155
|
+
"spinner",
|
|
5156
|
+
"reset"
|
|
5157
|
+
];
|
|
5158
|
+
const SPINNER_FRAMES = [
|
|
5159
|
+
"⠋",
|
|
5160
|
+
"⠙",
|
|
5161
|
+
"⠹",
|
|
5162
|
+
"⠸",
|
|
5163
|
+
"⠼",
|
|
5164
|
+
"⠴",
|
|
5165
|
+
"⠦",
|
|
5166
|
+
"⠧",
|
|
5167
|
+
"⠇",
|
|
5168
|
+
"⠏"
|
|
5169
|
+
];
|
|
5170
|
+
function get_working_indicator(ctx, mode) {
|
|
5171
|
+
switch (mode) {
|
|
5172
|
+
case "dot": return { frames: [ctx.ui.theme.fg("accent", "●")] };
|
|
5173
|
+
case "none": return { frames: [] };
|
|
5174
|
+
case "pulse": return {
|
|
5175
|
+
frames: [
|
|
5176
|
+
ctx.ui.theme.fg("dim", "·"),
|
|
5177
|
+
ctx.ui.theme.fg("muted", "•"),
|
|
5178
|
+
ctx.ui.theme.fg("accent", "●"),
|
|
5179
|
+
ctx.ui.theme.fg("muted", "•")
|
|
5180
|
+
],
|
|
5181
|
+
intervalMs: 120
|
|
5182
|
+
};
|
|
5183
|
+
case "spinner": return {
|
|
5184
|
+
frames: SPINNER_FRAMES.map((frame, index) => ctx.ui.theme.fg(index % 2 === 0 ? "accent" : "muted", frame)),
|
|
5185
|
+
intervalMs: 80
|
|
5186
|
+
};
|
|
5187
|
+
case "default": return;
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
function describe_working_indicator_mode(mode) {
|
|
5191
|
+
switch (mode) {
|
|
5192
|
+
case "dot": return "static dot";
|
|
5193
|
+
case "none": return "hidden";
|
|
5194
|
+
case "pulse": return "pulse";
|
|
5195
|
+
case "spinner": return "custom spinner";
|
|
5196
|
+
case "default": return "pi default spinner";
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
function parse_working_indicator_mode(input) {
|
|
5200
|
+
const normalized = input.trim().toLowerCase();
|
|
5201
|
+
if (!normalized) return null;
|
|
5202
|
+
if (normalized === "reset" || normalized === "default") return "default";
|
|
5203
|
+
if (normalized === "dot" || normalized === "none" || normalized === "pulse" || normalized === "spinner") return normalized;
|
|
5204
|
+
return null;
|
|
5205
|
+
}
|
|
5206
|
+
function apply_working_indicator(ctx, mode) {
|
|
5207
|
+
ctx.ui.setWorkingIndicator(get_working_indicator(ctx, mode));
|
|
5208
|
+
}
|
|
5209
|
+
async function working_indicator(pi) {
|
|
5210
|
+
let mode = load_working_indicator_config().mode;
|
|
5211
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
5212
|
+
mode = load_working_indicator_config().mode;
|
|
5213
|
+
apply_working_indicator(ctx, mode);
|
|
5214
|
+
});
|
|
5215
|
+
pi.registerCommand("working-indicator", {
|
|
5216
|
+
description: "Set the streaming working indicator: dot, pulse, none, spinner, or reset",
|
|
5217
|
+
getArgumentCompletions: (prefix) => {
|
|
5218
|
+
const value = prefix.trim().toLowerCase();
|
|
5219
|
+
return COMMAND_MODES.filter((entry) => entry.startsWith(value)).map((entry) => ({
|
|
5220
|
+
value: entry,
|
|
5221
|
+
label: entry
|
|
5222
|
+
}));
|
|
5223
|
+
},
|
|
5224
|
+
handler: async (args, ctx) => {
|
|
5225
|
+
const next = parse_working_indicator_mode(args);
|
|
5226
|
+
if (next === null) {
|
|
5227
|
+
if (!args.trim()) {
|
|
5228
|
+
ctx.ui.notify(`Working indicator: ${describe_working_indicator_mode(mode)}`, "info");
|
|
5229
|
+
return;
|
|
5230
|
+
}
|
|
5231
|
+
ctx.ui.notify("Usage: /working-indicator [dot|pulse|none|spinner|reset]", "error");
|
|
5232
|
+
return;
|
|
5233
|
+
}
|
|
5234
|
+
mode = next;
|
|
5235
|
+
save_working_indicator_config({
|
|
5236
|
+
version: 1,
|
|
5237
|
+
mode
|
|
5238
|
+
});
|
|
5239
|
+
apply_working_indicator(ctx, mode);
|
|
5240
|
+
ctx.ui.notify(`Working indicator set to: ${describe_working_indicator_mode(mode)}`, "info");
|
|
5241
|
+
}
|
|
5242
|
+
});
|
|
5243
|
+
}
|
|
5244
|
+
//#endregion
|
|
5002
5245
|
//#region src/api.ts
|
|
5003
5246
|
const BUILTIN_EXTENSION_FACTORIES = {
|
|
5004
5247
|
mcp,
|
|
@@ -5011,7 +5254,8 @@ const BUILTIN_EXTENSION_FACTORIES = {
|
|
|
5011
5254
|
lsp: lsp_default,
|
|
5012
5255
|
"session-name": session_name,
|
|
5013
5256
|
"confirm-destructive": confirm_destructive,
|
|
5014
|
-
"hooks-resolution": hooks_resolution_default
|
|
5257
|
+
"hooks-resolution": hooks_resolution_default,
|
|
5258
|
+
"working-indicator": working_indicator
|
|
5015
5259
|
};
|
|
5016
5260
|
const PACKAGE_THEME_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..", "themes");
|
|
5017
5261
|
const PI_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
|
|
@@ -5031,6 +5275,7 @@ function get_force_disabled_builtins(options) {
|
|
|
5031
5275
|
if (!options.session_name) force_disabled.add("session-name");
|
|
5032
5276
|
if (!options.confirm_destructive) force_disabled.add("confirm-destructive");
|
|
5033
5277
|
if (!options.hooks_resolution) force_disabled.add("hooks-resolution");
|
|
5278
|
+
if (!options.working_indicator) force_disabled.add("working-indicator");
|
|
5034
5279
|
return force_disabled;
|
|
5035
5280
|
}
|
|
5036
5281
|
function create_builtin_extension_factory(key, extension, force_disabled) {
|
|
@@ -5052,7 +5297,7 @@ function create_extensions_override(managed_inline_paths) {
|
|
|
5052
5297
|
};
|
|
5053
5298
|
}
|
|
5054
5299
|
async function create_my_pi(options = {}) {
|
|
5055
|
-
const { cwd = process.cwd(), agent_dir, extensions = [], extensionFactories: user_factories = [], mcp = true, skills = true, chain = true, filter_output = true, handoff = true, recall = true, prompt_presets = true, lsp = true, session_name = true, confirm_destructive = true, hooks_resolution = true, telemetry, telemetry_db_path, model, system_prompt, append_system_prompt } = options;
|
|
5300
|
+
const { cwd = process.cwd(), agent_dir, extensions = [], extensionFactories: user_factories = [], mcp = true, skills = true, chain = true, filter_output = true, handoff = true, recall = true, prompt_presets = true, lsp = true, session_name = true, confirm_destructive = true, hooks_resolution = true, working_indicator = true, telemetry, telemetry_db_path, model, system_prompt, append_system_prompt } = options;
|
|
5056
5301
|
const effective_agent_dir = resolve_agent_dir(cwd, agent_dir);
|
|
5057
5302
|
if (agent_dir) process.env[PI_AGENT_DIR_ENV] = effective_agent_dir;
|
|
5058
5303
|
const resolved_extensions = extensions.map((p) => resolve(cwd, p));
|
|
@@ -5067,7 +5312,8 @@ async function create_my_pi(options = {}) {
|
|
|
5067
5312
|
lsp,
|
|
5068
5313
|
session_name,
|
|
5069
5314
|
confirm_destructive,
|
|
5070
|
-
hooks_resolution
|
|
5315
|
+
hooks_resolution,
|
|
5316
|
+
working_indicator
|
|
5071
5317
|
});
|
|
5072
5318
|
const managed_extension_factories = [
|
|
5073
5319
|
create_telemetry_extension({
|
|
@@ -5125,4 +5371,4 @@ async function create_my_pi(options = {}) {
|
|
|
5125
5371
|
//#endregion
|
|
5126
5372
|
export { create_my_pi as n, runPrintMode$1 as r, InteractiveMode$1 as t };
|
|
5127
5373
|
|
|
5128
|
-
//# sourceMappingURL=api-
|
|
5374
|
+
//# sourceMappingURL=api-BVS4nqfD.js.map
|