my-pi 0.1.126 → 0.1.128
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 +1 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.js +1 -1
- package/dist/{builtin-registry-B1L__QH-.js → builtin-registry-C2Ineha8.js} +16 -2
- package/dist/builtin-registry-C2Ineha8.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{session-name-Cna2N2SX.js → session-name-CD6TVRnh.js} +39 -3
- package/dist/session-name-CD6TVRnh.js.map +1 -0
- package/package.json +11 -10
- package/dist/builtin-registry-B1L__QH-.js.map +0 -1
- package/dist/session-name-Cna2N2SX.js.map +0 -1
package/README.md
CHANGED
|
@@ -211,6 +211,7 @@ Full package list here:
|
|
|
211
211
|
| [`@spences10/pi-codex-usage`](./packages/pi-codex-usage/README.md) | OpenAI Codex usage in the footer status area |
|
|
212
212
|
| [`@spences10/pi-factory`](./packages/pi-factory/README.md) | Paused experimental workflow control plane (opt-in) |
|
|
213
213
|
| [`@spences10/pi-git-ui`](./packages/pi-git-ui/README.md) | Interactive source-control staging UI |
|
|
214
|
+
| [`@spences10/pi-kimi-usage`](./packages/pi-kimi-usage/README.md) | Kimi For Coding usage in the footer status area |
|
|
214
215
|
| [`@spences10/pi-lsp`](./packages/pi-lsp/README.md) | LSP-backed diagnostics and symbol tools |
|
|
215
216
|
| [`@spences10/pi-mcp`](./packages/pi-mcp/README.md) | MCP server integration and `/mcp` |
|
|
216
217
|
| [`@spences10/pi-nopeek`](./packages/pi-nopeek/README.md) | `nopeek` reminder for secret-safe environment loading |
|
package/dist/api.d.ts
CHANGED
|
@@ -96,6 +96,19 @@ declare const BUILTIN_EXTENSION_REGISTRY: readonly [{
|
|
|
96
96
|
readonly aliases: readonly ["codex-usage", "codex-status"];
|
|
97
97
|
readonly external_package_name: '@spences10/pi-codex-usage';
|
|
98
98
|
readonly load: () => Promise<typeof import("@spences10/pi-codex-usage").default>;
|
|
99
|
+
}, {
|
|
100
|
+
readonly key: 'kimi-usage';
|
|
101
|
+
readonly label: 'Kimi usage';
|
|
102
|
+
readonly docs_label: 'Kimi usage status';
|
|
103
|
+
readonly description: 'Kimi For Coding usage status for the footer';
|
|
104
|
+
readonly default_enabled: true;
|
|
105
|
+
readonly option_name: 'kimi_usage';
|
|
106
|
+
readonly cli_arg: 'no-kimi-usage';
|
|
107
|
+
readonly cli_flag: '--no-kimi-usage';
|
|
108
|
+
readonly cli_description: 'Disable Kimi usage footer status';
|
|
109
|
+
readonly aliases: readonly ["kimi-usage", "kimi-status"];
|
|
110
|
+
readonly external_package_name: '@spences10/pi-kimi-usage';
|
|
111
|
+
readonly load: () => Promise<typeof import("@spences10/pi-kimi-usage").default>;
|
|
99
112
|
}, {
|
|
100
113
|
readonly key: 'harness';
|
|
101
114
|
readonly label: 'Harness';
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-C2Ineha8.js";
|
|
2
2
|
import { n as save_settings, t as load_settings } from "./settings-CTk0ws43.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { existsSync, readdirSync } from "node:fs";
|
|
@@ -97,6 +97,20 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
97
97
|
external_package_name: "@spences10/pi-codex-usage",
|
|
98
98
|
load: async () => (await import("@spences10/pi-codex-usage")).default
|
|
99
99
|
},
|
|
100
|
+
{
|
|
101
|
+
key: "kimi-usage",
|
|
102
|
+
label: "Kimi usage",
|
|
103
|
+
docs_label: "Kimi usage status",
|
|
104
|
+
description: "Kimi For Coding usage status for the footer",
|
|
105
|
+
default_enabled: true,
|
|
106
|
+
option_name: "kimi_usage",
|
|
107
|
+
cli_arg: "no-kimi-usage",
|
|
108
|
+
cli_flag: "--no-kimi-usage",
|
|
109
|
+
cli_description: "Disable Kimi usage footer status",
|
|
110
|
+
aliases: ["kimi-usage", "kimi-status"],
|
|
111
|
+
external_package_name: "@spences10/pi-kimi-usage",
|
|
112
|
+
load: async () => (await import("@spences10/pi-kimi-usage")).default
|
|
113
|
+
},
|
|
100
114
|
{
|
|
101
115
|
key: "harness",
|
|
102
116
|
label: "Harness",
|
|
@@ -401,7 +415,7 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
401
415
|
],
|
|
402
416
|
reason: "UI-only session naming is only useful in interactive mode"
|
|
403
417
|
},
|
|
404
|
-
load: async () => (await import("./session-name-
|
|
418
|
+
load: async () => (await import("./session-name-CD6TVRnh.js")).default
|
|
405
419
|
},
|
|
406
420
|
{
|
|
407
421
|
key: "confirm-destructive",
|
|
@@ -498,4 +512,4 @@ const BUILTIN_EXTENSIONS = BUILTIN_EXTENSION_REGISTRY.map(({ load: _load, ...ext
|
|
|
498
512
|
//#endregion
|
|
499
513
|
export { BUILTIN_EXTENSION_REGISTRY as n, BUILTIN_EXTENSIONS as t };
|
|
500
514
|
|
|
501
|
-
//# sourceMappingURL=builtin-registry-
|
|
515
|
+
//# sourceMappingURL=builtin-registry-C2Ineha8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-registry-C2Ineha8.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\texternal_package_name?: string;\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\texternal_package_name: '@spences10/pi-context',\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\texternal_package_name: '@spences10/pi-mcp',\n\t\tload: async () => (await import('@spences10/pi-mcp')).default,\n\t},\n\t{\n\t\tkey: 'openrouter-fusion-config',\n\t\tlabel: 'OpenRouter Fusion config',\n\t\tdocs_label: 'OpenRouter Fusion config guard',\n\t\tdescription:\n\t\t\t'Keeps OpenRouter Fusion off Anthropic by injecting a non-Anthropic panel and judge',\n\t\tdefault_enabled: true,\n\t\toption_name: 'openrouter_fusion_config',\n\t\tcli_arg: 'no-openrouter-fusion-config',\n\t\tcli_flag: '--no-openrouter-fusion-config',\n\t\tcli_description: 'Disable OpenRouter Fusion non-Anthropic config',\n\t\taliases: ['openrouter-fusion-config', 'fusion-budget'],\n\t\tload: async () =>\n\t\t\t(await import('./openrouter-fusion-config/index.js')).default,\n\t},\n\t{\n\t\tkey: 'umans-provider',\n\t\tlabel: 'Umans provider',\n\t\tdocs_label: 'Umans provider',\n\t\tdescription:\n\t\t\t'Umans.ai Anthropic Messages provider with API key login support',\n\t\tdefault_enabled: true,\n\t\toption_name: 'umans_provider',\n\t\tcli_arg: 'no-umans-provider',\n\t\tcli_flag: '--no-umans-provider',\n\t\tcli_description: 'Disable built-in Umans provider',\n\t\taliases: ['umans-provider', 'umans'],\n\t\tload: async () =>\n\t\t\t(await import('./umans-provider/index.js')).default,\n\t},\n\t{\n\t\tkey: 'footer',\n\t\tlabel: 'Footer',\n\t\tdocs_label: 'Footer',\n\t\tdescription: 'Configurable interactive footer/statusline',\n\t\tdefault_enabled: true,\n\t\toption_name: 'footer',\n\t\tcli_arg: 'no-footer',\n\t\tcli_flag: '--no-footer',\n\t\tcli_description: 'Disable custom footer/statusline',\n\t\taliases: ['footer', 'statusline', 'status-line'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Footer only renders in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./footer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'codex-usage',\n\t\tlabel: 'Codex usage',\n\t\tdocs_label: 'Codex usage status',\n\t\tdescription: 'OpenAI Codex usage status for the footer',\n\t\tdefault_enabled: true,\n\t\toption_name: 'codex_usage',\n\t\tcli_arg: 'no-codex-usage',\n\t\tcli_flag: '--no-codex-usage',\n\t\tcli_description: 'Disable Codex usage footer status',\n\t\taliases: ['codex-usage', 'codex-status'],\n\t\texternal_package_name: '@spences10/pi-codex-usage',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-codex-usage')).default,\n\t},\n\t{\n\t\tkey: 'kimi-usage',\n\t\tlabel: 'Kimi usage',\n\t\tdocs_label: 'Kimi usage status',\n\t\tdescription: 'Kimi For Coding usage status for the footer',\n\t\tdefault_enabled: true,\n\t\toption_name: 'kimi_usage',\n\t\tcli_arg: 'no-kimi-usage',\n\t\tcli_flag: '--no-kimi-usage',\n\t\tcli_description: 'Disable Kimi usage footer status',\n\t\taliases: ['kimi-usage', 'kimi-status'],\n\t\texternal_package_name: '@spences10/pi-kimi-usage',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-kimi-usage')).default,\n\t},\n\t{\n\t\tkey: 'harness',\n\t\tlabel: 'Harness',\n\t\tdocs_label: 'Task harness runtime',\n\t\tdescription:\n\t\t\t'Ephemeral /tmp task harness runtime with tools, enforcement, and bundled skills',\n\t\tdefault_enabled: true,\n\t\toption_name: 'harness',\n\t\tcli_arg: 'no-harness',\n\t\tcli_flag: '--no-harness',\n\t\tcli_description: 'Disable task harness runtime',\n\t\taliases: ['harness', 'task-harness'],\n\t\texternal_package_name: '@spences10/pi-harness',\n\t\tload: async () => (await import('@spences10/pi-harness')).default,\n\t},\n\t{\n\t\tkey: 'factory',\n\t\tlabel: 'Software factory (experimental)',\n\t\tdocs_label: 'Experimental software-factory control plane',\n\t\tdescription:\n\t\t\t'Paused experimental workflow control plane; enable explicitly for Factory v1 evaluation only',\n\t\tdefault_enabled: false,\n\t\toption_name: 'factory',\n\t\tcli_arg: 'no-factory',\n\t\tcli_flag: '--no-factory',\n\t\tcli_description: 'Disable software-factory control plane',\n\t\taliases: ['factory', 'software-factory', 'control-plane'],\n\t\texternal_package_name: '@spences10/pi-factory',\n\t\tload: async () => (await import('@spences10/pi-factory')).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\texternal_package_name: '@spences10/pi-skills',\n\t\tload: async () => (await import('@spences10/pi-skills')).default,\n\t},\n\t{\n\t\tkey: 'skill-importer',\n\t\tlabel: 'Skill importer',\n\t\tdocs_label: 'Skill importer',\n\t\tdescription:\n\t\t\t'Import external Claude/plugin skills into Pi-native storage',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skill_importer',\n\t\tcli_arg: 'no-skill-importer',\n\t\tcli_flag: '--no-skill-importer',\n\t\tcli_description: 'Disable external skill importer extension',\n\t\taliases: ['skill-importer', 'import-skills', 'skill-import'],\n\t\texternal_package_name: '@spences10/pi-skill-importer',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-skill-importer')).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\texternal_package_name: '@spences10/pi-redact',\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\texternal_package_name: '@spences10/pi-recall',\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\texternal_package_name: '@spences10/pi-nopeek',\n\t\tload: async () => (await import('@spences10/pi-nopeek')).default,\n\t},\n\t{\n\t\tkey: 'observability',\n\t\tlabel: 'Observability',\n\t\tdocs_label: 'Live observability',\n\t\tdescription:\n\t\t\t'Optional live event stream and local browser dashboard',\n\t\tdefault_enabled: true,\n\t\toption_name: 'observability',\n\t\tcli_arg: 'no-observability',\n\t\tcli_flag: '--no-observability',\n\t\tcli_description: 'Disable live observability extension',\n\t\taliases: ['observability', 'obs', 'live-events'],\n\t\texternal_package_name: '@spences10/pi-observability',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-observability')).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\texternal_package_name: '@spences10/pi-omnisearch',\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\texternal_package_name: '@spences10/pi-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: 'turn-timer',\n\t\tlabel: 'Turn timer',\n\t\tdocs_label: 'Turn timer',\n\t\tdescription:\n\t\t\t'Live elapsed timer beside the working spinner with persisted turn durations',\n\t\tdefault_enabled: true,\n\t\toption_name: 'turn_timer',\n\t\tcli_arg: 'no-turn-timer',\n\t\tcli_flag: '--no-turn-timer',\n\t\tcli_description: 'Disable the working spinner turn timer',\n\t\taliases: ['turn-timer', 'timer', 'elapsed-time'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'The live timer is only useful in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./turn-timer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'git-ui',\n\t\tlabel: 'Git UI',\n\t\tdocs_label: 'Git staging UI',\n\t\tdescription: 'Interactive source control staging panel',\n\t\tdefault_enabled: true,\n\t\toption_name: 'git_ui',\n\t\tcli_arg: 'no-git-ui',\n\t\tcli_flag: '--no-git-ui',\n\t\tcli_description: 'Disable built-in Git staging UI',\n\t\taliases: ['git-ui', 'git', 'source-control', 'scm'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Git UI is only useful in interactive mode',\n\t\t},\n\t\texternal_package_name: '@spences10/pi-git-ui',\n\t\tload: async () => (await import('@spences10/pi-git-ui')).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\texternal_package_name: '@spences10/pi-lsp',\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\texternal_package_name: '@spences10/pi-confirm-destructive',\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\texternal_package_name: '@spences10/pi-svelte-guardrails',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-svelte-guardrails')).default,\n\t},\n\t{\n\t\tkey: 'coding-preferences',\n\t\tlabel: 'Coding preferences',\n\t\tdocs_label: 'Coding preferences',\n\t\tdescription:\n\t\t\t'Blocks configured coding workflow anti-patterns from JSON preferences',\n\t\tdefault_enabled: true,\n\t\toption_name: 'coding_preferences',\n\t\tcli_arg: 'no-coding-preferences',\n\t\tcli_flag: '--no-coding-preferences',\n\t\tcli_description: 'Disable coding preferences guardrails',\n\t\taliases: ['coding-preferences', 'preferences', 'prefs'],\n\t\texternal_package_name: '@spences10/pi-coding-preferences',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-coding-preferences')).default,\n\t},\n\t{\n\t\tkey: 'handoff',\n\t\tlabel: 'Handoff',\n\t\tdocs_label: 'Handoff',\n\t\tdescription:\n\t\t\t'Help command for Pi continuation primitives like /fork, /tree, /export, /import, and /share',\n\t\tdefault_enabled: true,\n\t\toption_name: 'handoff',\n\t\tcli_arg: 'no-handoff',\n\t\tcli_flag: '--no-handoff',\n\t\tcli_description: 'Disable handoff helper command',\n\t\taliases: ['handoff', 'continuation'],\n\t\tload: async () => (await import('./handoff/index.js')).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'Peer coordination between independently opened Pi sessions with groups, artifacts, and durable 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 peer-session team mode extension',\n\t\taliases: ['team-mode', 'team', 'teammates'],\n\t\texternal_package_name: '@spences10/pi-team-mode',\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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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-
|
|
2
|
+
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-C2Ineha8.js";
|
|
3
3
|
import { defineCommand, renderUsage, runMain } from "citty";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -20,15 +20,50 @@ Output ONLY the session name, nothing else.`;
|
|
|
20
20
|
const AUTO_NAME_THRESHOLD = 1;
|
|
21
21
|
const MAX_CHARS = 4e3;
|
|
22
22
|
const MAX_NAME_LEN = 50;
|
|
23
|
+
const MAX_ATTEMPTS = 3;
|
|
24
|
+
const RETRY_DELAYS_MS = [1500, 4e3];
|
|
23
25
|
function clean_name(value) {
|
|
24
26
|
return value.replace(/^["']|["']$/g, "").normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, MAX_NAME_LEN).replace(/-+$/g, "");
|
|
25
27
|
}
|
|
26
28
|
function truncate_conversation(value) {
|
|
27
29
|
return value.length > MAX_CHARS ? value.slice(0, MAX_CHARS) + "\n..." : value;
|
|
28
30
|
}
|
|
31
|
+
function is_transient_error(message) {
|
|
32
|
+
return /\b(429|500|502|503|529)\b/.test(message) || /overload|rate.?limit|temporarily unavailable|try again/i.test(message);
|
|
33
|
+
}
|
|
34
|
+
function sleep(ms, signal) {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const timer = setTimeout(resolve, ms);
|
|
37
|
+
signal?.addEventListener("abort", () => {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
resolve();
|
|
40
|
+
}, { once: true });
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function complete_with_retry(model, context, options) {
|
|
44
|
+
let last_error = /* @__PURE__ */ new Error("Unknown provider error");
|
|
45
|
+
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
46
|
+
if (attempt > 0) {
|
|
47
|
+
await sleep(RETRY_DELAYS_MS[attempt - 1], options.signal);
|
|
48
|
+
if (options.signal?.aborted) break;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const response = await complete(model, context, options);
|
|
52
|
+
if (response.stopReason !== "error") return response;
|
|
53
|
+
const message = response.errorMessage ?? "Provider error";
|
|
54
|
+
if (!is_transient_error(message)) return response;
|
|
55
|
+
last_error = new Error(message);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
if (options.signal?.aborted || !is_transient_error(message)) throw err;
|
|
59
|
+
last_error = err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw last_error;
|
|
63
|
+
}
|
|
29
64
|
async function generate_session_name(ctx, model, conversation_text, signal) {
|
|
30
65
|
const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
|
|
31
|
-
if (!auth.ok || !auth.apiKey) throw new Error(auth.ok ? `No
|
|
66
|
+
if (!auth.ok || !auth.apiKey && !auth.headers) throw new Error(auth.ok ? `No credentials for ${model.provider} (API key or OAuth login required)` : auth.error);
|
|
32
67
|
const user_message = {
|
|
33
68
|
role: "user",
|
|
34
69
|
content: [{
|
|
@@ -37,7 +72,7 @@ async function generate_session_name(ctx, model, conversation_text, signal) {
|
|
|
37
72
|
}],
|
|
38
73
|
timestamp: Date.now()
|
|
39
74
|
};
|
|
40
|
-
const response = await
|
|
75
|
+
const response = await complete_with_retry(model, {
|
|
41
76
|
systemPrompt: SYSTEM_PROMPT,
|
|
42
77
|
messages: [user_message]
|
|
43
78
|
}, {
|
|
@@ -46,6 +81,7 @@ async function generate_session_name(ctx, model, conversation_text, signal) {
|
|
|
46
81
|
signal
|
|
47
82
|
});
|
|
48
83
|
if (response.stopReason === "aborted") return null;
|
|
84
|
+
if (response.stopReason === "error") throw new Error(response.errorMessage ?? `Provider error from ${model.provider}`);
|
|
49
85
|
return clean_name(response.content.filter((c) => c.type === "text").map((c) => c.text.trim()).join(" "));
|
|
50
86
|
}
|
|
51
87
|
async function session_name(pi) {
|
|
@@ -119,4 +155,4 @@ async function session_name(pi) {
|
|
|
119
155
|
//#endregion
|
|
120
156
|
export { session_name as default };
|
|
121
157
|
|
|
122
|
-
//# sourceMappingURL=session-name-
|
|
158
|
+
//# sourceMappingURL=session-name-CD6TVRnh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-name-CD6TVRnh.js","names":[],"sources":["../src/extensions/session-name/index.ts"],"sourcesContent":["// Session name — AI-powered session naming\n// Adapted from Thomas Lopes' pi dotfiles\n\nimport { complete, type Message } from '@earendil-works/pi-ai/compat';\nimport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tSessionEntry,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\tBorderedLoader,\n\tconvertToLlm,\n\tserializeConversation,\n} from '@earendil-works/pi-coding-agent';\n\nconst SYSTEM_PROMPT = `You are a session naming assistant. Given a conversation history, generate a short, descriptive session name (2-5 words) that captures the main topic or task.\n\nGuidelines:\n- Be concise but specific\n- Use kebab-case only\n- Focus on the core task/question\n- Avoid generic names like \"discussion\" or \"conversation\"\n- No quotes, no punctuation at the end\n\nExamples:\n- \"fix auth bug\" -> \"fix-auth-bug\"\n- \"how do I deploy to vercel\" -> \"vercel-deployment\"\n- \"explain react hooks\" -> \"react-hooks-explanation\"\n- \"optimize database queries\" -> \"db-query-optimization\"\n\nOutput ONLY the session name, nothing else.`;\n\nconst AUTO_NAME_THRESHOLD = 1;\nconst MAX_CHARS = 4000;\nconst MAX_NAME_LEN = 50;\nconst MAX_ATTEMPTS = 3;\nconst RETRY_DELAYS_MS = [1_500, 4_000];\n\nexport function clean_name(value: string): string {\n\treturn value\n\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t.normalize('NFKD')\n\t\t.replace(/[\\u0300-\\u036f]/g, '')\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.slice(0, MAX_NAME_LEN)\n\t\t.replace(/-+$/g, '');\n}\n\nfunction truncate_conversation(value: string): string {\n\treturn value.length > MAX_CHARS\n\t\t? value.slice(0, MAX_CHARS) + '\\n...'\n\t\t: value;\n}\n\nexport function is_transient_error(message: string): boolean {\n\treturn (\n\t\t/\\b(429|500|502|503|529)\\b/.test(message) ||\n\t\t/overload|rate.?limit|temporarily unavailable|try again/i.test(\n\t\t\tmessage,\n\t\t)\n\t);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tconst timer = setTimeout(resolve, ms);\n\t\tsignal?.addEventListener(\n\t\t\t'abort',\n\t\t\t() => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n\nasync function complete_with_retry(\n\tmodel: Parameters<typeof complete>[0],\n\tcontext: Parameters<typeof complete>[1],\n\toptions: NonNullable<Parameters<typeof complete>[2]>,\n): Promise<Awaited<ReturnType<typeof complete>>> {\n\tlet last_error: unknown = new Error('Unknown provider error');\n\tfor (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {\n\t\tif (attempt > 0) {\n\t\t\tawait sleep(RETRY_DELAYS_MS[attempt - 1], options.signal);\n\t\t\tif (options.signal?.aborted) break;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await complete(model, context, options);\n\t\t\tif (response.stopReason !== 'error') return response;\n\t\t\tconst message = response.errorMessage ?? 'Provider error';\n\t\t\tif (!is_transient_error(message)) return response;\n\t\t\tlast_error = new Error(message);\n\t\t} catch (err) {\n\t\t\tconst message =\n\t\t\t\terr instanceof Error ? err.message : String(err);\n\t\t\tif (options.signal?.aborted || !is_transient_error(message)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tlast_error = err;\n\t\t}\n\t}\n\tthrow last_error;\n}\n\nasync function generate_session_name(\n\tctx: Pick<ExtensionCommandContext, 'modelRegistry'>,\n\tmodel: NonNullable<\n\t\tParameters<\n\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t>[1]['model']\n\t>,\n\tconversation_text: string,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok || (!auth.apiKey && !auth.headers)) {\n\t\tthrow new Error(\n\t\t\tauth.ok\n\t\t\t\t? `No credentials for ${model.provider} (API key or OAuth login required)`\n\t\t\t\t: auth.error,\n\t\t);\n\t}\n\n\tconst user_message: Message = {\n\t\trole: 'user',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'text',\n\t\t\t\ttext: `## Conversation History\\n\\n${truncate_conversation(conversation_text)}\\n\\nGenerate a concise session name for this conversation.`,\n\t\t\t},\n\t\t],\n\t\ttimestamp: Date.now(),\n\t};\n\n\tconst response = await complete_with_retry(\n\t\tmodel,\n\t\t{ systemPrompt: SYSTEM_PROMPT, messages: [user_message] },\n\t\t{ apiKey: auth.apiKey, headers: auth.headers, signal },\n\t);\n\n\tif (response.stopReason === 'aborted') {\n\t\treturn null;\n\t}\n\n\tif (response.stopReason === 'error') {\n\t\tthrow new Error(\n\t\t\tresponse.errorMessage ??\n\t\t\t\t`Provider error from ${model.provider}`,\n\t\t);\n\t}\n\n\treturn clean_name(\n\t\tresponse.content\n\t\t\t.filter(\n\t\t\t\t(c): c is { type: 'text'; text: string } => c.type === 'text',\n\t\t\t)\n\t\t\t.map((c) => c.text.trim())\n\t\t\t.join(' '),\n\t);\n}\n\nexport default async function session_name(pi: ExtensionAPI) {\n\tlet auto_named_attempted = false;\n\n\tpi.on('agent_end', async (_event, ctx) => {\n\t\tif (!ctx.hasUI || !ctx.model) return;\n\t\tif (pi.getSessionName() || auto_named_attempted) return;\n\n\t\tconst branch = ctx.sessionManager.getBranch();\n\t\tconst user_messages = branch.filter(\n\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\tentry.type === 'message' && entry.message.role === 'user',\n\t\t);\n\t\tif (user_messages.length < AUTO_NAME_THRESHOLD) return;\n\n\t\tauto_named_attempted = true;\n\t\tconst messages = branch\n\t\t\t.filter(\n\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\tentry.type === 'message',\n\t\t\t)\n\t\t\t.map((entry) => entry.message);\n\t\tif (messages.length === 0) return;\n\n\t\tconst conversation_text = serializeConversation(\n\t\t\tconvertToLlm(messages),\n\t\t);\n\n\t\tgenerate_session_name(ctx, ctx.model, conversation_text)\n\t\t\t.then((name) => {\n\t\t\t\tif (!name) return;\n\t\t\t\tpi.setSessionName(name);\n\t\t\t\tctx.ui.notify(`Auto-named: ${name}`, 'info');\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t});\n\t});\n\n\tpi.on('session_start', async () => {\n\t\tauto_named_attempted = false;\n\t});\n\n\tpi.registerCommand('session-name', {\n\t\tdescription:\n\t\t\t'Set, show, or auto-generate the current session name',\n\t\thandler: async (args, ctx) => {\n\t\t\tconst trimmed = args.trim();\n\n\t\t\tif (!trimmed) {\n\t\t\t\tconst current = pi.getSessionName();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcurrent ? `Session: ${current}` : 'No session name set',\n\t\t\t\t\t'info',\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (trimmed === '--auto' || trimmed === '-a') {\n\t\t\t\tif (!ctx.hasUI || !ctx.model) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t'Auto-naming requires interactive mode and a selected model',\n\t\t\t\t\t\t'error',\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst messages = branch\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\t\t\tentry.type === 'message',\n\t\t\t\t\t)\n\t\t\t\t\t.map((entry) => entry.message);\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tctx.ui.notify('No conversation to analyze', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst conversation_text = serializeConversation(\n\t\t\t\t\tconvertToLlm(messages),\n\t\t\t\t);\n\n\t\t\t\tconst result = await ctx.ui.custom<string | null>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst loader = new BorderedLoader(\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\t'Generating session name...',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tloader.onAbort = () => done(null);\n\n\t\t\t\t\t\tgenerate_session_name(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tctx.model!,\n\t\t\t\t\t\t\tconversation_text,\n\t\t\t\t\t\t\tloader.signal,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.then(done)\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t\t\t\t\t\tdone(null);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn loader;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (result === null) {\n\t\t\t\t\tctx.ui.notify('Auto-naming cancelled', 'info');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result) {\n\t\t\t\t\tctx.ui.notify('Failed to generate name', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tpi.setSessionName(result);\n\t\t\t\tctx.ui.notify(`Session named: ${result}`, 'info');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpi.setSessionName(clean_name(trimmed));\n\t\t\tctx.ui.notify(`Session named: ${clean_name(trimmed)}`, 'info');\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.128",
|
|
4
4
|
"description": "Composable pi coding agent with MCP, LSP, prompt presets, and local eval telemetry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@earendil-works/pi-ai": "0.
|
|
47
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
48
|
-
"@earendil-works/pi-tui": "0.
|
|
46
|
+
"@earendil-works/pi-ai": "0.83.0",
|
|
47
|
+
"@earendil-works/pi-coding-agent": "0.83.0",
|
|
48
|
+
"@earendil-works/pi-tui": "0.83.0",
|
|
49
49
|
"citty": "^0.2.2",
|
|
50
50
|
"@spences10/pi-project-trust": "0.0.19",
|
|
51
51
|
"@spences10/pi-settings": "0.0.3",
|
|
52
|
-
"@spences10/pi-
|
|
53
|
-
"@spences10/pi-
|
|
52
|
+
"@spences10/pi-tui-modal": "0.0.24",
|
|
53
|
+
"@spences10/pi-themes": "0.0.10"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@changesets/cli": "^2.31.0",
|
|
@@ -62,14 +62,15 @@
|
|
|
62
62
|
},
|
|
63
63
|
"optionalDependencies": {
|
|
64
64
|
"@spences10/pi-child-env": "0.1.10",
|
|
65
|
-
"@spences10/pi-codex-usage": "0.0.
|
|
65
|
+
"@spences10/pi-codex-usage": "0.0.2",
|
|
66
66
|
"@spences10/pi-coding-preferences": "0.0.15",
|
|
67
67
|
"@spences10/pi-confirm-destructive": "0.0.20",
|
|
68
|
+
"@spences10/pi-context": "0.1.15",
|
|
68
69
|
"@spences10/pi-factory": "0.0.13",
|
|
69
70
|
"@spences10/pi-footer": "0.0.16",
|
|
70
|
-
"@spences10/pi-context": "0.1.15",
|
|
71
71
|
"@spences10/pi-git-ui": "0.0.16",
|
|
72
72
|
"@spences10/pi-harness": "0.0.10",
|
|
73
|
+
"@spences10/pi-kimi-usage": "0.0.2",
|
|
73
74
|
"@spences10/pi-lsp": "0.0.44",
|
|
74
75
|
"@spences10/pi-mcp": "0.0.58",
|
|
75
76
|
"@spences10/pi-nopeek": "0.0.16",
|
|
@@ -78,10 +79,10 @@
|
|
|
78
79
|
"@spences10/pi-omnisearch": "0.0.15",
|
|
79
80
|
"@spences10/pi-redact": "0.0.14",
|
|
80
81
|
"@spences10/pi-skill-importer": "0.0.13",
|
|
81
|
-
"@spences10/pi-skills": "0.0.36",
|
|
82
82
|
"@spences10/pi-sqlite-tools": "0.0.15",
|
|
83
|
-
"@spences10/pi-
|
|
83
|
+
"@spences10/pi-skills": "0.0.36",
|
|
84
84
|
"@spences10/pi-team-mode": "0.0.57",
|
|
85
|
+
"@spences10/pi-svelte-guardrails": "0.0.16",
|
|
85
86
|
"@spences10/pi-telemetry": "0.0.33"
|
|
86
87
|
},
|
|
87
88
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-registry-B1L__QH-.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\texternal_package_name?: string;\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\texternal_package_name: '@spences10/pi-context',\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\texternal_package_name: '@spences10/pi-mcp',\n\t\tload: async () => (await import('@spences10/pi-mcp')).default,\n\t},\n\t{\n\t\tkey: 'openrouter-fusion-config',\n\t\tlabel: 'OpenRouter Fusion config',\n\t\tdocs_label: 'OpenRouter Fusion config guard',\n\t\tdescription:\n\t\t\t'Keeps OpenRouter Fusion off Anthropic by injecting a non-Anthropic panel and judge',\n\t\tdefault_enabled: true,\n\t\toption_name: 'openrouter_fusion_config',\n\t\tcli_arg: 'no-openrouter-fusion-config',\n\t\tcli_flag: '--no-openrouter-fusion-config',\n\t\tcli_description: 'Disable OpenRouter Fusion non-Anthropic config',\n\t\taliases: ['openrouter-fusion-config', 'fusion-budget'],\n\t\tload: async () =>\n\t\t\t(await import('./openrouter-fusion-config/index.js')).default,\n\t},\n\t{\n\t\tkey: 'umans-provider',\n\t\tlabel: 'Umans provider',\n\t\tdocs_label: 'Umans provider',\n\t\tdescription:\n\t\t\t'Umans.ai Anthropic Messages provider with API key login support',\n\t\tdefault_enabled: true,\n\t\toption_name: 'umans_provider',\n\t\tcli_arg: 'no-umans-provider',\n\t\tcli_flag: '--no-umans-provider',\n\t\tcli_description: 'Disable built-in Umans provider',\n\t\taliases: ['umans-provider', 'umans'],\n\t\tload: async () =>\n\t\t\t(await import('./umans-provider/index.js')).default,\n\t},\n\t{\n\t\tkey: 'footer',\n\t\tlabel: 'Footer',\n\t\tdocs_label: 'Footer',\n\t\tdescription: 'Configurable interactive footer/statusline',\n\t\tdefault_enabled: true,\n\t\toption_name: 'footer',\n\t\tcli_arg: 'no-footer',\n\t\tcli_flag: '--no-footer',\n\t\tcli_description: 'Disable custom footer/statusline',\n\t\taliases: ['footer', 'statusline', 'status-line'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Footer only renders in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./footer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'codex-usage',\n\t\tlabel: 'Codex usage',\n\t\tdocs_label: 'Codex usage status',\n\t\tdescription: 'OpenAI Codex usage status for the footer',\n\t\tdefault_enabled: true,\n\t\toption_name: 'codex_usage',\n\t\tcli_arg: 'no-codex-usage',\n\t\tcli_flag: '--no-codex-usage',\n\t\tcli_description: 'Disable Codex usage footer status',\n\t\taliases: ['codex-usage', 'codex-status'],\n\t\texternal_package_name: '@spences10/pi-codex-usage',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-codex-usage')).default,\n\t},\n\t{\n\t\tkey: 'harness',\n\t\tlabel: 'Harness',\n\t\tdocs_label: 'Task harness runtime',\n\t\tdescription:\n\t\t\t'Ephemeral /tmp task harness runtime with tools, enforcement, and bundled skills',\n\t\tdefault_enabled: true,\n\t\toption_name: 'harness',\n\t\tcli_arg: 'no-harness',\n\t\tcli_flag: '--no-harness',\n\t\tcli_description: 'Disable task harness runtime',\n\t\taliases: ['harness', 'task-harness'],\n\t\texternal_package_name: '@spences10/pi-harness',\n\t\tload: async () => (await import('@spences10/pi-harness')).default,\n\t},\n\t{\n\t\tkey: 'factory',\n\t\tlabel: 'Software factory (experimental)',\n\t\tdocs_label: 'Experimental software-factory control plane',\n\t\tdescription:\n\t\t\t'Paused experimental workflow control plane; enable explicitly for Factory v1 evaluation only',\n\t\tdefault_enabled: false,\n\t\toption_name: 'factory',\n\t\tcli_arg: 'no-factory',\n\t\tcli_flag: '--no-factory',\n\t\tcli_description: 'Disable software-factory control plane',\n\t\taliases: ['factory', 'software-factory', 'control-plane'],\n\t\texternal_package_name: '@spences10/pi-factory',\n\t\tload: async () => (await import('@spences10/pi-factory')).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\texternal_package_name: '@spences10/pi-skills',\n\t\tload: async () => (await import('@spences10/pi-skills')).default,\n\t},\n\t{\n\t\tkey: 'skill-importer',\n\t\tlabel: 'Skill importer',\n\t\tdocs_label: 'Skill importer',\n\t\tdescription:\n\t\t\t'Import external Claude/plugin skills into Pi-native storage',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skill_importer',\n\t\tcli_arg: 'no-skill-importer',\n\t\tcli_flag: '--no-skill-importer',\n\t\tcli_description: 'Disable external skill importer extension',\n\t\taliases: ['skill-importer', 'import-skills', 'skill-import'],\n\t\texternal_package_name: '@spences10/pi-skill-importer',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-skill-importer')).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\texternal_package_name: '@spences10/pi-redact',\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\texternal_package_name: '@spences10/pi-recall',\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\texternal_package_name: '@spences10/pi-nopeek',\n\t\tload: async () => (await import('@spences10/pi-nopeek')).default,\n\t},\n\t{\n\t\tkey: 'observability',\n\t\tlabel: 'Observability',\n\t\tdocs_label: 'Live observability',\n\t\tdescription:\n\t\t\t'Optional live event stream and local browser dashboard',\n\t\tdefault_enabled: true,\n\t\toption_name: 'observability',\n\t\tcli_arg: 'no-observability',\n\t\tcli_flag: '--no-observability',\n\t\tcli_description: 'Disable live observability extension',\n\t\taliases: ['observability', 'obs', 'live-events'],\n\t\texternal_package_name: '@spences10/pi-observability',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-observability')).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\texternal_package_name: '@spences10/pi-omnisearch',\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\texternal_package_name: '@spences10/pi-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: 'turn-timer',\n\t\tlabel: 'Turn timer',\n\t\tdocs_label: 'Turn timer',\n\t\tdescription:\n\t\t\t'Live elapsed timer beside the working spinner with persisted turn durations',\n\t\tdefault_enabled: true,\n\t\toption_name: 'turn_timer',\n\t\tcli_arg: 'no-turn-timer',\n\t\tcli_flag: '--no-turn-timer',\n\t\tcli_description: 'Disable the working spinner turn timer',\n\t\taliases: ['turn-timer', 'timer', 'elapsed-time'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'The live timer is only useful in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./turn-timer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'git-ui',\n\t\tlabel: 'Git UI',\n\t\tdocs_label: 'Git staging UI',\n\t\tdescription: 'Interactive source control staging panel',\n\t\tdefault_enabled: true,\n\t\toption_name: 'git_ui',\n\t\tcli_arg: 'no-git-ui',\n\t\tcli_flag: '--no-git-ui',\n\t\tcli_description: 'Disable built-in Git staging UI',\n\t\taliases: ['git-ui', 'git', 'source-control', 'scm'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Git UI is only useful in interactive mode',\n\t\t},\n\t\texternal_package_name: '@spences10/pi-git-ui',\n\t\tload: async () => (await import('@spences10/pi-git-ui')).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\texternal_package_name: '@spences10/pi-lsp',\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\texternal_package_name: '@spences10/pi-confirm-destructive',\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\texternal_package_name: '@spences10/pi-svelte-guardrails',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-svelte-guardrails')).default,\n\t},\n\t{\n\t\tkey: 'coding-preferences',\n\t\tlabel: 'Coding preferences',\n\t\tdocs_label: 'Coding preferences',\n\t\tdescription:\n\t\t\t'Blocks configured coding workflow anti-patterns from JSON preferences',\n\t\tdefault_enabled: true,\n\t\toption_name: 'coding_preferences',\n\t\tcli_arg: 'no-coding-preferences',\n\t\tcli_flag: '--no-coding-preferences',\n\t\tcli_description: 'Disable coding preferences guardrails',\n\t\taliases: ['coding-preferences', 'preferences', 'prefs'],\n\t\texternal_package_name: '@spences10/pi-coding-preferences',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-coding-preferences')).default,\n\t},\n\t{\n\t\tkey: 'handoff',\n\t\tlabel: 'Handoff',\n\t\tdocs_label: 'Handoff',\n\t\tdescription:\n\t\t\t'Help command for Pi continuation primitives like /fork, /tree, /export, /import, and /share',\n\t\tdefault_enabled: true,\n\t\toption_name: 'handoff',\n\t\tcli_arg: 'no-handoff',\n\t\tcli_flag: '--no-handoff',\n\t\tcli_description: 'Disable handoff helper command',\n\t\taliases: ['handoff', 'continuation'],\n\t\tload: async () => (await import('./handoff/index.js')).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'Peer coordination between independently opened Pi sessions with groups, artifacts, and durable 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 peer-session team mode extension',\n\t\taliases: ['team-mode', 'team', 'teammates'],\n\t\texternal_package_name: '@spences10/pi-team-mode',\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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-name-Cna2N2SX.js","names":[],"sources":["../src/extensions/session-name/index.ts"],"sourcesContent":["// Session name — AI-powered session naming\n// Adapted from Thomas Lopes' pi dotfiles\n\nimport { complete, type Message } from '@earendil-works/pi-ai/compat';\nimport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tSessionEntry,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\tBorderedLoader,\n\tconvertToLlm,\n\tserializeConversation,\n} from '@earendil-works/pi-coding-agent';\n\nconst SYSTEM_PROMPT = `You are a session naming assistant. Given a conversation history, generate a short, descriptive session name (2-5 words) that captures the main topic or task.\n\nGuidelines:\n- Be concise but specific\n- Use kebab-case only\n- Focus on the core task/question\n- Avoid generic names like \"discussion\" or \"conversation\"\n- No quotes, no punctuation at the end\n\nExamples:\n- \"fix auth bug\" -> \"fix-auth-bug\"\n- \"how do I deploy to vercel\" -> \"vercel-deployment\"\n- \"explain react hooks\" -> \"react-hooks-explanation\"\n- \"optimize database queries\" -> \"db-query-optimization\"\n\nOutput ONLY the session name, nothing else.`;\n\nconst AUTO_NAME_THRESHOLD = 1;\nconst MAX_CHARS = 4000;\nconst MAX_NAME_LEN = 50;\n\nfunction clean_name(value: string): string {\n\treturn value\n\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t.normalize('NFKD')\n\t\t.replace(/[\\u0300-\\u036f]/g, '')\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.slice(0, MAX_NAME_LEN)\n\t\t.replace(/-+$/g, '');\n}\n\nfunction truncate_conversation(value: string): string {\n\treturn value.length > MAX_CHARS\n\t\t? value.slice(0, MAX_CHARS) + '\\n...'\n\t\t: value;\n}\n\nasync function generate_session_name(\n\tctx: Pick<ExtensionCommandContext, 'modelRegistry'>,\n\tmodel: NonNullable<\n\t\tParameters<\n\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t>[1]['model']\n\t>,\n\tconversation_text: string,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok || !auth.apiKey) {\n\t\tthrow new Error(\n\t\t\tauth.ok ? `No API key for ${model.provider}` : auth.error,\n\t\t);\n\t}\n\n\tconst user_message: Message = {\n\t\trole: 'user',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'text',\n\t\t\t\ttext: `## Conversation History\\n\\n${truncate_conversation(conversation_text)}\\n\\nGenerate a concise session name for this conversation.`,\n\t\t\t},\n\t\t],\n\t\ttimestamp: Date.now(),\n\t};\n\n\tconst response = await complete(\n\t\tmodel,\n\t\t{ systemPrompt: SYSTEM_PROMPT, messages: [user_message] },\n\t\t{ apiKey: auth.apiKey, headers: auth.headers, signal },\n\t);\n\n\tif (response.stopReason === 'aborted') {\n\t\treturn null;\n\t}\n\n\treturn clean_name(\n\t\tresponse.content\n\t\t\t.filter(\n\t\t\t\t(c): c is { type: 'text'; text: string } => c.type === 'text',\n\t\t\t)\n\t\t\t.map((c) => c.text.trim())\n\t\t\t.join(' '),\n\t);\n}\n\nexport default async function session_name(pi: ExtensionAPI) {\n\tlet auto_named_attempted = false;\n\n\tpi.on('agent_end', async (_event, ctx) => {\n\t\tif (!ctx.hasUI || !ctx.model) return;\n\t\tif (pi.getSessionName() || auto_named_attempted) return;\n\n\t\tconst branch = ctx.sessionManager.getBranch();\n\t\tconst user_messages = branch.filter(\n\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\tentry.type === 'message' && entry.message.role === 'user',\n\t\t);\n\t\tif (user_messages.length < AUTO_NAME_THRESHOLD) return;\n\n\t\tauto_named_attempted = true;\n\t\tconst messages = branch\n\t\t\t.filter(\n\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\tentry.type === 'message',\n\t\t\t)\n\t\t\t.map((entry) => entry.message);\n\t\tif (messages.length === 0) return;\n\n\t\tconst conversation_text = serializeConversation(\n\t\t\tconvertToLlm(messages),\n\t\t);\n\n\t\tgenerate_session_name(ctx, ctx.model, conversation_text)\n\t\t\t.then((name) => {\n\t\t\t\tif (!name) return;\n\t\t\t\tpi.setSessionName(name);\n\t\t\t\tctx.ui.notify(`Auto-named: ${name}`, 'info');\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t});\n\t});\n\n\tpi.on('session_start', async () => {\n\t\tauto_named_attempted = false;\n\t});\n\n\tpi.registerCommand('session-name', {\n\t\tdescription:\n\t\t\t'Set, show, or auto-generate the current session name',\n\t\thandler: async (args, ctx) => {\n\t\t\tconst trimmed = args.trim();\n\n\t\t\tif (!trimmed) {\n\t\t\t\tconst current = pi.getSessionName();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcurrent ? `Session: ${current}` : 'No session name set',\n\t\t\t\t\t'info',\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (trimmed === '--auto' || trimmed === '-a') {\n\t\t\t\tif (!ctx.hasUI || !ctx.model) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t'Auto-naming requires interactive mode and a selected model',\n\t\t\t\t\t\t'error',\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst messages = branch\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\t\t\tentry.type === 'message',\n\t\t\t\t\t)\n\t\t\t\t\t.map((entry) => entry.message);\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tctx.ui.notify('No conversation to analyze', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst conversation_text = serializeConversation(\n\t\t\t\t\tconvertToLlm(messages),\n\t\t\t\t);\n\n\t\t\t\tconst result = await ctx.ui.custom<string | null>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst loader = new BorderedLoader(\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\t'Generating session name...',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tloader.onAbort = () => done(null);\n\n\t\t\t\t\t\tgenerate_session_name(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tctx.model!,\n\t\t\t\t\t\t\tconversation_text,\n\t\t\t\t\t\t\tloader.signal,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.then(done)\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t\t\t\t\t\tdone(null);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn loader;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (result === null) {\n\t\t\t\t\tctx.ui.notify('Auto-naming cancelled', 'info');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result) {\n\t\t\t\t\tctx.ui.notify('Failed to generate name', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tpi.setSessionName(result);\n\t\t\t\tctx.ui.notify(`Session named: ${result}`, 'info');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpi.setSessionName(clean_name(trimmed));\n\t\t\tctx.ui.notify(`Session named: ${clean_name(trimmed)}`, 'info');\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|