my-pi 0.3.5 → 0.3.6
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.d.ts +0 -22
- package/dist/api.js +9 -16
- package/dist/api.js.map +1 -1
- package/dist/{builtin-registry-wSfsQBi4.js → builtin-registry-C0CQdd45.js} +10 -11
- package/dist/{builtin-registry-wSfsQBi4.js.map → builtin-registry-C0CQdd45.js.map} +1 -1
- package/dist/{handoff-C6wR2mSG.js → handoff-B2wpybTf.js} +2 -3
- package/dist/{handoff-C6wR2mSG.js.map → handoff-B2wpybTf.js.map} +1 -1
- package/dist/{hooks-resolution-qlhPfMFJ.js → hooks-resolution-kzoVsQAX.js} +8 -15
- package/dist/{hooks-resolution-qlhPfMFJ.js.map → hooks-resolution-kzoVsQAX.js.map} +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/{openrouter-fusion-config-BWsHBPQv.js → openrouter-fusion-config-CPXLfmCA.js} +3 -4
- package/dist/{openrouter-fusion-config-BWsHBPQv.js.map → openrouter-fusion-config-CPXLfmCA.js.map} +1 -1
- package/dist/{prompt-presets-XraV03Ed.js → prompt-presets-DOn1oZFJ.js} +11 -21
- package/dist/{prompt-presets-XraV03Ed.js.map → prompt-presets-DOn1oZFJ.js.map} +1 -1
- package/dist/{session-name-CD6TVRnh.js → session-name-qyrX-OES.js} +2 -3
- package/dist/{session-name-CD6TVRnh.js.map → session-name-qyrX-OES.js.map} +1 -1
- package/dist/{settings-BCn3P9qH.js → settings-UYlhEo3S.js} +6 -11
- package/dist/{settings-BCn3P9qH.js.map → settings-UYlhEo3S.js.map} +1 -1
- package/dist/{startup-screen-DUeBWuAc.js → startup-screen-D5YGuwge.js} +2 -3
- package/dist/{startup-screen-DUeBWuAc.js.map → startup-screen-D5YGuwge.js.map} +1 -1
- package/dist/{turn-timer-CoyDI4gQ.js → turn-timer-mowT6nwv.js} +2 -3
- package/dist/{turn-timer-CoyDI4gQ.js.map → turn-timer-mowT6nwv.js.map} +1 -1
- package/dist/{umans-provider-C2UJ4qkO.js → umans-provider-DIupQTRK.js} +2 -3
- package/dist/{umans-provider-C2UJ4qkO.js.map → umans-provider-DIupQTRK.js.map} +1 -1
- package/package.json +10 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BorderedLoader, convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { complete } from "@earendil-works/pi-ai/compat";
|
|
3
|
-
|
|
3
|
+
// src/extensions/session-name/index.ts
|
|
4
4
|
const 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.
|
|
5
5
|
|
|
6
6
|
Guidelines:
|
|
@@ -152,7 +152,6 @@ async function session_name(pi) {
|
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
|
-
//#endregion
|
|
156
155
|
export { session_name as default };
|
|
157
156
|
|
|
158
|
-
//# sourceMappingURL=session-name-
|
|
157
|
+
//# sourceMappingURL=session-name-qyrX-OES.js.map
|
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"file":"session-name-qyrX-OES.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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"}
|
|
@@ -3,7 +3,7 @@ import { basename, dirname, join } from "node:path";
|
|
|
3
3
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { get_settings_path, read_settings, write_settings } from "@spences10/pi-settings";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
-
|
|
6
|
+
// src/settings/schema.ts
|
|
7
7
|
const DEFAULT_SETTINGS = {
|
|
8
8
|
version: 1,
|
|
9
9
|
extensions: { enabled: {} }
|
|
@@ -21,8 +21,7 @@ function normalize_settings(value) {
|
|
|
21
21
|
extensions: { enabled }
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
//#region src/settings/current.ts
|
|
24
|
+
// src/settings/current.ts
|
|
26
25
|
function current_settings_exists() {
|
|
27
26
|
return existsSync(get_settings_path());
|
|
28
27
|
}
|
|
@@ -37,8 +36,7 @@ function ensure_current_settings() {
|
|
|
37
36
|
if (!current_settings_exists()) write_current_settings(DEFAULT_SETTINGS);
|
|
38
37
|
return read_current_settings();
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
//#region src/settings/legacy.ts
|
|
39
|
+
// src/settings/legacy.ts
|
|
42
40
|
function get_legacy_builtin_extensions_config_path() {
|
|
43
41
|
const xdg = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
44
42
|
return join(xdg, "my-pi", "extensions.json");
|
|
@@ -76,8 +74,7 @@ function find_legacy_settings_files() {
|
|
|
76
74
|
function has_legacy_settings_files() {
|
|
77
75
|
return Object.values(find_legacy_settings_files()).some(Boolean);
|
|
78
76
|
}
|
|
79
|
-
|
|
80
|
-
//#region src/settings/migrate.ts
|
|
77
|
+
// src/settings/migrate.ts
|
|
81
78
|
function timestamp_for_filename(date = /* @__PURE__ */ new Date()) {
|
|
82
79
|
return date.toISOString().replace(/[:.]/g, "-");
|
|
83
80
|
}
|
|
@@ -162,8 +159,7 @@ function migrate_legacy_settings() {
|
|
|
162
159
|
settings: normalize_settings(settings)
|
|
163
160
|
};
|
|
164
161
|
}
|
|
165
|
-
|
|
166
|
-
//#region src/settings/index.ts
|
|
162
|
+
// src/settings/index.ts
|
|
167
163
|
function load_settings() {
|
|
168
164
|
if (has_legacy_settings_files()) return migrate_legacy_settings().settings;
|
|
169
165
|
return ensure_current_settings();
|
|
@@ -171,7 +167,6 @@ function load_settings() {
|
|
|
171
167
|
function save_settings(settings) {
|
|
172
168
|
write_current_settings(settings);
|
|
173
169
|
}
|
|
174
|
-
//#endregion
|
|
175
170
|
export { save_settings as n, load_settings as t };
|
|
176
171
|
|
|
177
|
-
//# sourceMappingURL=settings-
|
|
172
|
+
//# sourceMappingURL=settings-UYlhEo3S.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-BCn3P9qH.js","names":[],"sources":["../src/settings/schema.ts","../src/settings/current.ts","../src/settings/legacy.ts","../src/settings/migrate.ts","../src/settings/index.ts"],"sourcesContent":["import type { BuiltinExtensionKey } from '../extensions/builtin-registry.js';\n\nexport interface MyPiSettings {\n\tversion: 1;\n\textensions: {\n\t\tenabled: Partial<Record<BuiltinExtensionKey, boolean>>;\n\t};\n\tmcp?: { policy?: unknown };\n\tcodingPreferences?: unknown;\n\tpromptPresets?: { global?: unknown; state?: unknown };\n\topenRouterFusion?: {\n\t\tanalysisModels?: string[];\n\t\tjudgeModel?: string;\n\t\tforce?: boolean;\n\t};\n\ttrust?: Record<string, unknown>;\n\tpackages?: Record<string, unknown>;\n}\n\nexport const DEFAULT_SETTINGS: MyPiSettings = {\n\tversion: 1,\n\textensions: {\n\t\tenabled: {},\n\t},\n};\n\nexport function normalize_settings(value: unknown): MyPiSettings {\n\tconst raw = value as Partial<MyPiSettings> | null | undefined;\n\tconst enabled: MyPiSettings['extensions']['enabled'] = {};\n\tconst raw_enabled = raw?.extensions?.enabled;\n\tif (raw_enabled && typeof raw_enabled === 'object') {\n\t\tfor (const [key, state] of Object.entries(raw_enabled)) {\n\t\t\tif (typeof state === 'boolean') {\n\t\t\t\tenabled[key as BuiltinExtensionKey] = state;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\t...(raw && typeof raw === 'object' ? raw : {}),\n\t\tversion: 1,\n\t\textensions: { enabled },\n\t};\n}\n","import {\n\tget_settings_path,\n\tread_settings,\n\twrite_settings,\n} from '@spences10/pi-settings';\nimport { existsSync } from 'node:fs';\nimport {\n\tDEFAULT_SETTINGS,\n\tnormalize_settings,\n\ttype MyPiSettings,\n} from './schema.js';\n\nexport { get_settings_path } from '@spences10/pi-settings';\n\nexport function current_settings_exists(): boolean {\n\treturn existsSync(get_settings_path());\n}\n\nexport function read_current_settings(): MyPiSettings {\n\tif (!current_settings_exists()) return { ...DEFAULT_SETTINGS };\n\treturn normalize_settings(read_settings());\n}\n\nexport function write_current_settings(settings: MyPiSettings): void {\n\twrite_settings(settings);\n}\n\nexport function ensure_current_settings(): MyPiSettings {\n\tif (!current_settings_exists())\n\t\twrite_current_settings(DEFAULT_SETTINGS);\n\treturn read_current_settings();\n}\n","import { getAgentDir } from '@earendil-works/pi-coding-agent';\n// Temporary migration bridge: keep for two minor releases after\n// my-pi-settings.json ships, then remove with migrate.ts and related tests.\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { type BuiltinExtensionKey } from '../extensions/builtin-registry.js';\n\nexport interface LegacyBuiltinExtensionsConfig {\n\tversion?: number;\n\tenabled?: Partial<Record<BuiltinExtensionKey, boolean>>;\n}\n\nexport interface LegacySettingsFiles {\n\textensions?: {\n\t\tpath: string;\n\t\tconfig: LegacyBuiltinExtensionsConfig;\n\t};\n\tmcpPolicy?: { path: string; config: unknown };\n\tcodingPreferences?: { path: string; config: unknown };\n\tpromptPresets?: { path: string; config: unknown };\n\tpromptPresetState?: { path: string; config: unknown };\n\ttrustedHooks?: { path: string; config: unknown };\n\ttrustedMcpProjects?: { path: string; config: unknown };\n\ttrustedLspBinaries?: { path: string; config: unknown };\n\ttelemetry?: { path: string; config: unknown };\n\tfooter?: { path: string; config: unknown };\n\tskills?: { path: string; config: unknown };\n\tsvelteGuardrails?: { path: string; config: unknown };\n\tcontext?: { path: string; config: unknown };\n}\n\nexport function get_legacy_builtin_extensions_config_path(): string {\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn join(xdg, 'my-pi', 'extensions.json');\n}\n\nfunction read_json_file<T>(path: string): T | undefined {\n\tif (!existsSync(path)) return undefined;\n\treturn JSON.parse(readFileSync(path, 'utf-8')) as T;\n}\n\nfunction maybe_file<T>(\n\tpath: string,\n): { path: string; config: T } | undefined {\n\tconst config = read_json_file<T>(path);\n\treturn config === undefined ? undefined : { path, config };\n}\n\nexport function find_legacy_settings_files(): LegacySettingsFiles {\n\tconst agent = getAgentDir();\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn {\n\t\textensions: maybe_file<LegacyBuiltinExtensionsConfig>(\n\t\t\tget_legacy_builtin_extensions_config_path(),\n\t\t),\n\t\tmcpPolicy: maybe_file(join(agent, 'mcp-policy.json')),\n\t\tcodingPreferences: maybe_file(\n\t\t\tjoin(agent, 'coding-preferences.json'),\n\t\t),\n\t\tpromptPresets: maybe_file(join(agent, 'presets.json')),\n\t\tpromptPresetState: maybe_file(\n\t\t\tjoin(agent, 'prompt-preset-state.json'),\n\t\t),\n\t\ttrustedHooks: maybe_file(join(agent, 'trusted-hooks.json')),\n\t\ttrustedMcpProjects: maybe_file(\n\t\t\tjoin(agent, 'trusted-mcp-projects.json'),\n\t\t),\n\t\ttrustedLspBinaries: maybe_file(\n\t\t\tjoin(agent, 'trusted-lsp-binaries.json'),\n\t\t),\n\t\ttelemetry: maybe_file(join(agent, 'telemetry.json')),\n\t\tfooter: maybe_file(join(agent, 'extensions', 'pi-footer.json')),\n\t\tskills: maybe_file(join(xdg, 'my-pi', 'skills.json')),\n\t\tsvelteGuardrails: maybe_file(\n\t\t\tjoin(xdg, 'my-pi', 'svelte-guardrails.json'),\n\t\t),\n\t\tcontext: maybe_file(join(xdg, 'my-pi', 'context.json')),\n\t};\n}\n\nexport function has_legacy_settings_files(): boolean {\n\treturn Object.values(find_legacy_settings_files()).some(Boolean);\n}\n","import { getAgentDir } from '@earendil-works/pi-coding-agent';\nimport {\n\tread_settings,\n\twrite_settings,\n} from '@spences10/pi-settings';\nimport {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\trenameSync,\n\tunlinkSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { find_legacy_settings_files } from './legacy.js';\nimport { normalize_settings, type MyPiSettings } from './schema.js';\n\nexport interface SettingsMigrationResult {\n\tmigrated: boolean;\n\tbackup_dir?: string;\n\tmoved_files: string[];\n\tsettings: MyPiSettings;\n}\n\nfunction timestamp_for_filename(date = new Date()): string {\n\treturn date.toISOString().replace(/[:.]/g, '-');\n}\n\nfunction backup_path_for(\n\toriginal_path: string,\n\tbackup_dir: string,\n): string {\n\tconst parent = basename(dirname(original_path));\n\treturn join(backup_dir, `${parent}-${basename(original_path)}`);\n}\n\nfunction move_file_to_backup(source: string, target: string): void {\n\ttry {\n\t\trenameSync(source, target);\n\t} catch (error) {\n\t\tif (\n\t\t\terror instanceof Error &&\n\t\t\t'code' in error &&\n\t\t\terror.code === 'EXDEV'\n\t\t) {\n\t\t\tcopyFileSync(source, target);\n\t\t\tunlinkSync(source);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function migrate_legacy_settings(): SettingsMigrationResult {\n\tconst legacy = find_legacy_settings_files();\n\tconst entries = Object.values(legacy).filter(\n\t\t(entry) => entry !== undefined,\n\t);\n\tconst settings = read_settings();\n\n\tif (legacy.extensions) {\n\t\tsettings.extensions = {\n\t\t\t...settings.extensions,\n\t\t\tenabled: {\n\t\t\t\t...settings.extensions?.enabled,\n\t\t\t\t...legacy.extensions.config.enabled,\n\t\t\t},\n\t\t};\n\t}\n\tif (legacy.mcpPolicy) {\n\t\tsettings.mcp = {\n\t\t\t...settings.mcp,\n\t\t\tpolicy: legacy.mcpPolicy.config,\n\t\t};\n\t}\n\tif (legacy.codingPreferences) {\n\t\tsettings.codingPreferences = legacy.codingPreferences.config;\n\t}\n\tif (legacy.promptPresets || legacy.promptPresetState) {\n\t\tsettings.promptPresets = {\n\t\t\t...settings.promptPresets,\n\t\t\t...(legacy.promptPresets && {\n\t\t\t\tglobal: legacy.promptPresets.config,\n\t\t\t}),\n\t\t\t...(legacy.promptPresetState && {\n\t\t\t\tstate: legacy.promptPresetState.config,\n\t\t\t}),\n\t\t};\n\t}\n\tsettings.trust = {\n\t\t...settings.trust,\n\t\t...(legacy.trustedHooks && { hooks: legacy.trustedHooks.config }),\n\t\t...(legacy.trustedMcpProjects && {\n\t\t\tmcpProjects: legacy.trustedMcpProjects.config,\n\t\t}),\n\t\t...(legacy.trustedLspBinaries && {\n\t\t\tlspBinaries: legacy.trustedLspBinaries.config,\n\t\t}),\n\t};\n\tsettings.packages = {\n\t\t...settings.packages,\n\t\t...(legacy.telemetry && { telemetry: legacy.telemetry.config }),\n\t\t...(legacy.footer && { footer: legacy.footer.config }),\n\t\t...(legacy.skills && { skills: legacy.skills.config }),\n\t\t...(legacy.svelteGuardrails && {\n\t\t\tsvelteGuardrails: legacy.svelteGuardrails.config,\n\t\t}),\n\t\t...(legacy.context && { context: legacy.context.config }),\n\t};\n\n\twrite_settings(settings);\n\n\tif (entries.length === 0) {\n\t\treturn {\n\t\t\tmigrated: false,\n\t\t\tmoved_files: [],\n\t\t\tsettings: normalize_settings(settings),\n\t\t};\n\t}\n\n\tconst backup_dir = join(\n\t\tgetAgentDir(),\n\t\t`legacy-config-backup-${timestamp_for_filename()}`,\n\t);\n\tmkdirSync(backup_dir, { recursive: true, mode: 0o700 });\n\n\tconst moved_files: string[] = [];\n\tfor (const entry of entries) {\n\t\tif (!existsSync(entry.path)) continue;\n\t\tconst target = backup_path_for(entry.path, backup_dir);\n\t\tmove_file_to_backup(entry.path, target);\n\t\tmoved_files.push(entry.path);\n\t}\n\n\twriteFileSync(\n\t\tjoin(backup_dir, 'migration-report.json'),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tcreated_at: new Date().toISOString(),\n\t\t\t\tsettings_path: join(getAgentDir(), 'my-pi-settings.json'),\n\t\t\t\tmoved_files,\n\t\t\t},\n\t\t\tnull,\n\t\t\t'\\t',\n\t\t) + '\\n',\n\t\t{ mode: 0o600 },\n\t);\n\n\treturn {\n\t\tmigrated: true,\n\t\tbackup_dir,\n\t\tmoved_files,\n\t\tsettings: normalize_settings(settings),\n\t};\n}\n","import {\n\tensure_current_settings,\n\tread_current_settings,\n\twrite_current_settings,\n} from './current.js';\nimport { has_legacy_settings_files } from './legacy.js';\nimport { migrate_legacy_settings } from './migrate.js';\nimport type { MyPiSettings } from './schema.js';\n\nexport { get_settings_path } from './current.js';\nexport { migrate_legacy_settings } from './migrate.js';\nexport type { MyPiSettings } from './schema.js';\n\nexport function load_settings(): MyPiSettings {\n\tif (has_legacy_settings_files())\n\t\treturn migrate_legacy_settings().settings;\n\treturn ensure_current_settings();\n}\n\nexport function save_settings(settings: MyPiSettings): void {\n\twrite_current_settings(settings);\n}\n\nexport function update_settings(\n\tupdater: (settings: MyPiSettings) => MyPiSettings,\n): MyPiSettings {\n\tconst next = updater(read_current_settings());\n\twrite_current_settings(next);\n\treturn next;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"settings-UYlhEo3S.js","names":[],"sources":["../src/settings/schema.ts","../src/settings/current.ts","../src/settings/legacy.ts","../src/settings/migrate.ts","../src/settings/index.ts"],"sourcesContent":["import type { BuiltinExtensionKey } from '../extensions/builtin-registry.js';\n\nexport interface MyPiSettings {\n\tversion: 1;\n\textensions: {\n\t\tenabled: Partial<Record<BuiltinExtensionKey, boolean>>;\n\t};\n\tmcp?: { policy?: unknown };\n\tcodingPreferences?: unknown;\n\tpromptPresets?: { global?: unknown; state?: unknown };\n\topenRouterFusion?: {\n\t\tanalysisModels?: string[];\n\t\tjudgeModel?: string;\n\t\tforce?: boolean;\n\t};\n\ttrust?: Record<string, unknown>;\n\tpackages?: Record<string, unknown>;\n}\n\nexport const DEFAULT_SETTINGS: MyPiSettings = {\n\tversion: 1,\n\textensions: {\n\t\tenabled: {},\n\t},\n};\n\nexport function normalize_settings(value: unknown): MyPiSettings {\n\tconst raw = value as Partial<MyPiSettings> | null | undefined;\n\tconst enabled: MyPiSettings['extensions']['enabled'] = {};\n\tconst raw_enabled = raw?.extensions?.enabled;\n\tif (raw_enabled && typeof raw_enabled === 'object') {\n\t\tfor (const [key, state] of Object.entries(raw_enabled)) {\n\t\t\tif (typeof state === 'boolean') {\n\t\t\t\tenabled[key as BuiltinExtensionKey] = state;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\t...(raw && typeof raw === 'object' ? raw : {}),\n\t\tversion: 1,\n\t\textensions: { enabled },\n\t};\n}\n","import {\n\tget_settings_path,\n\tread_settings,\n\twrite_settings,\n} from '@spences10/pi-settings';\nimport { existsSync } from 'node:fs';\nimport {\n\tDEFAULT_SETTINGS,\n\tnormalize_settings,\n\ttype MyPiSettings,\n} from './schema.js';\n\nexport { get_settings_path } from '@spences10/pi-settings';\n\nexport function current_settings_exists(): boolean {\n\treturn existsSync(get_settings_path());\n}\n\nexport function read_current_settings(): MyPiSettings {\n\tif (!current_settings_exists()) return { ...DEFAULT_SETTINGS };\n\treturn normalize_settings(read_settings());\n}\n\nexport function write_current_settings(settings: MyPiSettings): void {\n\twrite_settings(settings);\n}\n\nexport function ensure_current_settings(): MyPiSettings {\n\tif (!current_settings_exists())\n\t\twrite_current_settings(DEFAULT_SETTINGS);\n\treturn read_current_settings();\n}\n","import { getAgentDir } from '@earendil-works/pi-coding-agent';\n// Temporary migration bridge: keep for two minor releases after\n// my-pi-settings.json ships, then remove with migrate.ts and related tests.\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { type BuiltinExtensionKey } from '../extensions/builtin-registry.js';\n\nexport interface LegacyBuiltinExtensionsConfig {\n\tversion?: number;\n\tenabled?: Partial<Record<BuiltinExtensionKey, boolean>>;\n}\n\nexport interface LegacySettingsFiles {\n\textensions?: {\n\t\tpath: string;\n\t\tconfig: LegacyBuiltinExtensionsConfig;\n\t};\n\tmcpPolicy?: { path: string; config: unknown };\n\tcodingPreferences?: { path: string; config: unknown };\n\tpromptPresets?: { path: string; config: unknown };\n\tpromptPresetState?: { path: string; config: unknown };\n\ttrustedHooks?: { path: string; config: unknown };\n\ttrustedMcpProjects?: { path: string; config: unknown };\n\ttrustedLspBinaries?: { path: string; config: unknown };\n\ttelemetry?: { path: string; config: unknown };\n\tfooter?: { path: string; config: unknown };\n\tskills?: { path: string; config: unknown };\n\tsvelteGuardrails?: { path: string; config: unknown };\n\tcontext?: { path: string; config: unknown };\n}\n\nexport function get_legacy_builtin_extensions_config_path(): string {\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn join(xdg, 'my-pi', 'extensions.json');\n}\n\nfunction read_json_file<T>(path: string): T | undefined {\n\tif (!existsSync(path)) return undefined;\n\treturn JSON.parse(readFileSync(path, 'utf-8')) as T;\n}\n\nfunction maybe_file<T>(\n\tpath: string,\n): { path: string; config: T } | undefined {\n\tconst config = read_json_file<T>(path);\n\treturn config === undefined ? undefined : { path, config };\n}\n\nexport function find_legacy_settings_files(): LegacySettingsFiles {\n\tconst agent = getAgentDir();\n\tconst xdg =\n\t\tprocess.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n\treturn {\n\t\textensions: maybe_file<LegacyBuiltinExtensionsConfig>(\n\t\t\tget_legacy_builtin_extensions_config_path(),\n\t\t),\n\t\tmcpPolicy: maybe_file(join(agent, 'mcp-policy.json')),\n\t\tcodingPreferences: maybe_file(\n\t\t\tjoin(agent, 'coding-preferences.json'),\n\t\t),\n\t\tpromptPresets: maybe_file(join(agent, 'presets.json')),\n\t\tpromptPresetState: maybe_file(\n\t\t\tjoin(agent, 'prompt-preset-state.json'),\n\t\t),\n\t\ttrustedHooks: maybe_file(join(agent, 'trusted-hooks.json')),\n\t\ttrustedMcpProjects: maybe_file(\n\t\t\tjoin(agent, 'trusted-mcp-projects.json'),\n\t\t),\n\t\ttrustedLspBinaries: maybe_file(\n\t\t\tjoin(agent, 'trusted-lsp-binaries.json'),\n\t\t),\n\t\ttelemetry: maybe_file(join(agent, 'telemetry.json')),\n\t\tfooter: maybe_file(join(agent, 'extensions', 'pi-footer.json')),\n\t\tskills: maybe_file(join(xdg, 'my-pi', 'skills.json')),\n\t\tsvelteGuardrails: maybe_file(\n\t\t\tjoin(xdg, 'my-pi', 'svelte-guardrails.json'),\n\t\t),\n\t\tcontext: maybe_file(join(xdg, 'my-pi', 'context.json')),\n\t};\n}\n\nexport function has_legacy_settings_files(): boolean {\n\treturn Object.values(find_legacy_settings_files()).some(Boolean);\n}\n","import { getAgentDir } from '@earendil-works/pi-coding-agent';\nimport {\n\tread_settings,\n\twrite_settings,\n} from '@spences10/pi-settings';\nimport {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\trenameSync,\n\tunlinkSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { find_legacy_settings_files } from './legacy.js';\nimport { normalize_settings, type MyPiSettings } from './schema.js';\n\nexport interface SettingsMigrationResult {\n\tmigrated: boolean;\n\tbackup_dir?: string;\n\tmoved_files: string[];\n\tsettings: MyPiSettings;\n}\n\nfunction timestamp_for_filename(date = new Date()): string {\n\treturn date.toISOString().replace(/[:.]/g, '-');\n}\n\nfunction backup_path_for(\n\toriginal_path: string,\n\tbackup_dir: string,\n): string {\n\tconst parent = basename(dirname(original_path));\n\treturn join(backup_dir, `${parent}-${basename(original_path)}`);\n}\n\nfunction move_file_to_backup(source: string, target: string): void {\n\ttry {\n\t\trenameSync(source, target);\n\t} catch (error) {\n\t\tif (\n\t\t\terror instanceof Error &&\n\t\t\t'code' in error &&\n\t\t\terror.code === 'EXDEV'\n\t\t) {\n\t\t\tcopyFileSync(source, target);\n\t\t\tunlinkSync(source);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function migrate_legacy_settings(): SettingsMigrationResult {\n\tconst legacy = find_legacy_settings_files();\n\tconst entries = Object.values(legacy).filter(\n\t\t(entry) => entry !== undefined,\n\t);\n\tconst settings = read_settings();\n\n\tif (legacy.extensions) {\n\t\tsettings.extensions = {\n\t\t\t...settings.extensions,\n\t\t\tenabled: {\n\t\t\t\t...settings.extensions?.enabled,\n\t\t\t\t...legacy.extensions.config.enabled,\n\t\t\t},\n\t\t};\n\t}\n\tif (legacy.mcpPolicy) {\n\t\tsettings.mcp = {\n\t\t\t...settings.mcp,\n\t\t\tpolicy: legacy.mcpPolicy.config,\n\t\t};\n\t}\n\tif (legacy.codingPreferences) {\n\t\tsettings.codingPreferences = legacy.codingPreferences.config;\n\t}\n\tif (legacy.promptPresets || legacy.promptPresetState) {\n\t\tsettings.promptPresets = {\n\t\t\t...settings.promptPresets,\n\t\t\t...(legacy.promptPresets && {\n\t\t\t\tglobal: legacy.promptPresets.config,\n\t\t\t}),\n\t\t\t...(legacy.promptPresetState && {\n\t\t\t\tstate: legacy.promptPresetState.config,\n\t\t\t}),\n\t\t};\n\t}\n\tsettings.trust = {\n\t\t...settings.trust,\n\t\t...(legacy.trustedHooks && { hooks: legacy.trustedHooks.config }),\n\t\t...(legacy.trustedMcpProjects && {\n\t\t\tmcpProjects: legacy.trustedMcpProjects.config,\n\t\t}),\n\t\t...(legacy.trustedLspBinaries && {\n\t\t\tlspBinaries: legacy.trustedLspBinaries.config,\n\t\t}),\n\t};\n\tsettings.packages = {\n\t\t...settings.packages,\n\t\t...(legacy.telemetry && { telemetry: legacy.telemetry.config }),\n\t\t...(legacy.footer && { footer: legacy.footer.config }),\n\t\t...(legacy.skills && { skills: legacy.skills.config }),\n\t\t...(legacy.svelteGuardrails && {\n\t\t\tsvelteGuardrails: legacy.svelteGuardrails.config,\n\t\t}),\n\t\t...(legacy.context && { context: legacy.context.config }),\n\t};\n\n\twrite_settings(settings);\n\n\tif (entries.length === 0) {\n\t\treturn {\n\t\t\tmigrated: false,\n\t\t\tmoved_files: [],\n\t\t\tsettings: normalize_settings(settings),\n\t\t};\n\t}\n\n\tconst backup_dir = join(\n\t\tgetAgentDir(),\n\t\t`legacy-config-backup-${timestamp_for_filename()}`,\n\t);\n\tmkdirSync(backup_dir, { recursive: true, mode: 0o700 });\n\n\tconst moved_files: string[] = [];\n\tfor (const entry of entries) {\n\t\tif (!existsSync(entry.path)) continue;\n\t\tconst target = backup_path_for(entry.path, backup_dir);\n\t\tmove_file_to_backup(entry.path, target);\n\t\tmoved_files.push(entry.path);\n\t}\n\n\twriteFileSync(\n\t\tjoin(backup_dir, 'migration-report.json'),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tcreated_at: new Date().toISOString(),\n\t\t\t\tsettings_path: join(getAgentDir(), 'my-pi-settings.json'),\n\t\t\t\tmoved_files,\n\t\t\t},\n\t\t\tnull,\n\t\t\t'\\t',\n\t\t) + '\\n',\n\t\t{ mode: 0o600 },\n\t);\n\n\treturn {\n\t\tmigrated: true,\n\t\tbackup_dir,\n\t\tmoved_files,\n\t\tsettings: normalize_settings(settings),\n\t};\n}\n","import {\n\tensure_current_settings,\n\tread_current_settings,\n\twrite_current_settings,\n} from './current.js';\nimport { has_legacy_settings_files } from './legacy.js';\nimport { migrate_legacy_settings } from './migrate.js';\nimport type { MyPiSettings } from './schema.js';\n\nexport { get_settings_path } from './current.js';\nexport { migrate_legacy_settings } from './migrate.js';\nexport type { MyPiSettings } from './schema.js';\n\nexport function load_settings(): MyPiSettings {\n\tif (has_legacy_settings_files())\n\t\treturn migrate_legacy_settings().settings;\n\treturn ensure_current_settings();\n}\n\nexport function save_settings(settings: MyPiSettings): void {\n\twrite_current_settings(settings);\n}\n\nexport function update_settings(\n\tupdater: (settings: MyPiSettings) => MyPiSettings,\n): MyPiSettings {\n\tconst next = updater(read_current_settings());\n\twrite_current_settings(next);\n\treturn next;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
3
|
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
4
|
-
|
|
4
|
+
// src/extensions/startup-screen/index.ts
|
|
5
5
|
const RESET = "\x1B[0m";
|
|
6
6
|
const BOLD = "\x1B[1m";
|
|
7
7
|
const TRUECOLOR_FG_PREFIX = "\x1B[38;2;";
|
|
@@ -212,7 +212,6 @@ function startup_screen_extension(pi) {
|
|
|
212
212
|
}
|
|
213
213
|
});
|
|
214
214
|
}
|
|
215
|
-
//#endregion
|
|
216
215
|
export { startup_screen_extension as default };
|
|
217
216
|
|
|
218
|
-
//# sourceMappingURL=startup-screen-
|
|
217
|
+
//# sourceMappingURL=startup-screen-D5YGuwge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-screen-DUeBWuAc.js","names":[],"sources":["../src/extensions/startup-screen/index.ts"],"sourcesContent":["import type {\n\tExtensionAPI,\n\tExtensionContext,\n\tTheme,\n\tThemeColor,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\ttruncateToWidth,\n\tvisibleWidth,\n} from '@earendil-works/pi-tui';\nimport { readFileSync } from 'node:fs';\nimport { basename } from 'node:path';\n\ntype Rgb = [number, number, number];\n\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst TRUECOLOR_FG_PREFIX = '\\x1b[38;2;';\nconst XTERM_FG_PREFIX = '\\x1b[38;5;';\n\nconst FALLBACK_PALETTE: Rgb[] = [\n\t[22, 83, 189],\n\t[48, 129, 247],\n\t[93, 171, 255],\n\t[151, 205, 255],\n\t[93, 171, 255],\n\t[48, 129, 247],\n];\n\nconst THEME_GRADIENT_TOKENS: ThemeColor[] = [\n\t'accent',\n\t'borderAccent',\n\t'mdHeading',\n\t'syntaxFunction',\n\t'thinkingHigh',\n\t'mdCode',\n];\n\nconst XTERM_CUBE_VALUES = [0, 95, 135, 175, 215, 255] as const;\nconst XTERM_GRAY_START = 232;\n\nconst TITLE_LINES = [\n\t'███╗ ███╗ ██████╗ ██╗',\n\t'████╗ ████║ ██╗ ██╗ ██╔══██╗ ',\n\t'██╔████╔██║ ╚██╗ ██╔╝ ████╗ ██████╔╝██╗',\n\t'██║╚██╔╝██║ ╚████╔╝ ╚═══╝ ██╔═══╝ ██║',\n\t'██║ ╚═╝ ██║ ╚██╔╝ ██║ ██║',\n\t'╚═╝ ╚═╝ ██╔╝ ╚═╝ ╚═╝',\n] as const;\n\nconst TITLE_WIDTH = Math.max(\n\t...TITLE_LINES.map((line) => line.length),\n);\n\nfunction read_my_pi_version(): string {\n\tconst candidates = [\n\t\tnew URL('../../../package.json', import.meta.url),\n\t\tnew URL('../package.json', import.meta.url),\n\t];\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(\n\t\t\t\treadFileSync(candidate, 'utf-8'),\n\t\t\t);\n\t\t\tconst version = (parsed as { version?: unknown } | null)\n\t\t\t\t?.version;\n\t\t\tif (typeof version === 'string') return version;\n\t\t} catch {\n\t\t\t// Try the next source/distro-relative location.\n\t\t}\n\t}\n\n\treturn 'dev';\n}\n\nconst MY_PI_VERSION = read_my_pi_version();\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn Math.round(a + (b - a) * t);\n}\n\nfunction sample_gradient(position: number, palette: Rgb[]): Rgb {\n\tconst wrapped = ((position % 1) + 1) % 1;\n\tconst scaled = wrapped * palette.length;\n\tconst index = Math.floor(scaled);\n\tconst next_index = (index + 1) % palette.length;\n\tconst t = scaled - index;\n\tconst a = palette[index]!;\n\tconst b = palette[next_index]!;\n\treturn [mix(a[0], b[0], t), mix(a[1], b[1], t), mix(a[2], b[2], t)];\n}\n\nfunction ansi_fg([r, g, b]: Rgb, text: string): string {\n\treturn `\\x1b[38;2;${r};${g};${b}m${text}${RESET}`;\n}\n\nfunction rgb_from_xterm(index: number): Rgb | undefined {\n\tif (index < 0 || index > 255) return undefined;\n\tif (index < 16) return undefined;\n\tif (index >= XTERM_GRAY_START) {\n\t\tconst gray = 8 + (index - XTERM_GRAY_START) * 10;\n\t\treturn [gray, gray, gray];\n\t}\n\n\tconst cube = index - 16;\n\tconst r = XTERM_CUBE_VALUES[Math.floor(cube / 36)]!;\n\tconst g = XTERM_CUBE_VALUES[Math.floor((cube % 36) / 6)]!;\n\tconst b = XTERM_CUBE_VALUES[cube % 6]!;\n\treturn [r, g, b];\n}\n\nfunction ansi_params(\n\tansi: string,\n\tprefix: string,\n): string[] | undefined {\n\tif (!ansi.startsWith(prefix)) return undefined;\n\tconst end = ansi.indexOf('m', prefix.length);\n\tif (end === -1) return undefined;\n\treturn ansi.slice(prefix.length, end).split(';');\n}\n\nfunction rgb_from_ansi(ansi: string): Rgb | undefined {\n\tconst truecolor = ansi_params(ansi, TRUECOLOR_FG_PREFIX);\n\tif (truecolor?.length === 3) {\n\t\treturn [\n\t\t\tNumber(truecolor[0]),\n\t\t\tNumber(truecolor[1]),\n\t\t\tNumber(truecolor[2]),\n\t\t];\n\t}\n\n\tconst xterm = ansi_params(ansi, XTERM_FG_PREFIX);\n\treturn xterm?.length === 1\n\t\t? rgb_from_xterm(Number(xterm[0]))\n\t\t: undefined;\n}\n\nfunction theme_gradient_palette(theme: Theme): Rgb[] {\n\tconst palette: Rgb[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const token of THEME_GRADIENT_TOKENS) {\n\t\tconst rgb = rgb_from_ansi(theme.getFgAnsi(token));\n\t\tif (!rgb) continue;\n\t\tconst key = rgb.join(',');\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tpalette.push(rgb);\n\t}\n\n\treturn palette.length >= 2 ? palette : FALLBACK_PALETTE;\n}\n\nfunction gradient_text(\n\ttext: string,\n\tphase: number,\n\tpalette: Rgb[],\n): string {\n\tconst chars = text.split('');\n\tconst span = Math.max(chars.length - 1, 1);\n\treturn chars\n\t\t.map((char, index) => {\n\t\t\tif (char === ' ') return char;\n\t\t\treturn ansi_fg(\n\t\t\t\tsample_gradient(index / span + phase, palette),\n\t\t\t\tchar,\n\t\t\t);\n\t\t})\n\t\t.join('');\n}\n\nfunction center_line(line: string, width: number): string {\n\tconst clipped =\n\t\tvisibleWidth(line) > width\n\t\t\t? truncateToWidth(line, width, '')\n\t\t\t: line;\n\tconst padding = Math.max(\n\t\t0,\n\t\tMath.floor((width - visibleWidth(clipped)) / 2),\n\t);\n\treturn `${' '.repeat(padding)}${clipped}`;\n}\n\nfunction color_line(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tline: string,\n\tphase: number,\n): string {\n\treturn theme.getColorMode() === 'truecolor'\n\t\t? gradient_text(line, phase, palette)\n\t\t: theme.fg('accent', line);\n}\n\nfunction gradient_or_theme(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tline: string,\n\tphase: number,\n): string {\n\treturn theme.getColorMode() === 'truecolor'\n\t\t? `${BOLD}${gradient_text(line, phase, palette)}${RESET}`\n\t\t: theme.bold(theme.fg('accent', line));\n}\n\nfunction render_brand(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\twidth: number,\n): string {\n\treturn gradient_or_theme(\n\t\ttheme,\n\t\tpalette,\n\t\tcenter_line(`My-Pi v${MY_PI_VERSION}`, width),\n\t\t0.12,\n\t);\n}\n\nfunction render_subtitle(\n\tctx: ExtensionContext,\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tmodel_id: string,\n\twidth: number,\n): string {\n\tconst project = basename(ctx.cwd) || ctx.cwd;\n\tconst subtitle = center_line(`${model_id} · ${project}`, width);\n\treturn gradient_or_theme(theme, palette, subtitle, 0.18);\n}\n\nexport function render_startup_header(\n\tctx: ExtensionContext,\n\ttheme: Theme,\n\twidth: number,\n\tmodel_id = ctx.model?.id ?? 'no model selected',\n): string[] {\n\tif (width < 24) {\n\t\treturn [\n\t\t\tcenter_line(\n\t\t\t\ttheme.bold(theme.fg('accent', `My-Pi v${MY_PI_VERSION}`)),\n\t\t\t\twidth,\n\t\t\t),\n\t\t\tcenter_line(\n\t\t\t\t`${model_id} · ${basename(ctx.cwd) || ctx.cwd}`,\n\t\t\t\twidth,\n\t\t\t),\n\t\t];\n\t}\n\n\tconst palette = theme_gradient_palette(theme);\n\tconst logo = TITLE_LINES.map((line, row) =>\n\t\tcolor_line(\n\t\t\ttheme,\n\t\t\tpalette,\n\t\t\tcenter_line(line.padEnd(TITLE_WIDTH), width),\n\t\t\trow * 0.045,\n\t\t),\n\t);\n\n\treturn [\n\t\t'',\n\t\trender_brand(theme, palette, width),\n\t\t...logo,\n\t\trender_subtitle(ctx, theme, palette, model_id, width),\n\t\t'',\n\t];\n}\n\nexport default function startup_screen_extension(\n\tpi: ExtensionAPI,\n): void {\n\tlet request_render: (() => void) | undefined;\n\tlet current_model_id = 'no model selected';\n\n\tfunction install_header(ctx: ExtensionContext): void {\n\t\tctx.ui.setHeader((tui, theme) => {\n\t\t\trequest_render = () => tui.requestRender();\n\t\t\treturn {\n\t\t\t\tinvalidate() {\n\t\t\t\t\ttui.requestRender();\n\t\t\t\t},\n\t\t\t\trender(width: number) {\n\t\t\t\t\treturn render_startup_header(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\tcurrent_model_id,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t}\n\n\tpi.on('session_start', async (_event, ctx) => {\n\t\tcurrent_model_id = ctx.model?.id ?? 'no model selected';\n\t\tif (!ctx.hasUI) return;\n\t\tinstall_header(ctx);\n\t});\n\n\tpi.on('model_select', (event) => {\n\t\tcurrent_model_id = event.model.id;\n\t\trequest_render?.();\n\t});\n\n\tpi.on('session_shutdown', (_event, ctx) => {\n\t\tif (ctx.hasUI) ctx.ui.setHeader(undefined);\n\t});\n\n\tpi.registerCommand('builtin-header', {\n\t\tdescription: 'Restore the built-in pi startup header',\n\t\thandler: async (_args, ctx) => {\n\t\t\tctx.ui.setHeader(undefined);\n\t\t\tctx.ui.notify('Built-in startup header restored', 'info');\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"startup-screen-D5YGuwge.js","names":[],"sources":["../src/extensions/startup-screen/index.ts"],"sourcesContent":["import type {\n\tExtensionAPI,\n\tExtensionContext,\n\tTheme,\n\tThemeColor,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\ttruncateToWidth,\n\tvisibleWidth,\n} from '@earendil-works/pi-tui';\nimport { readFileSync } from 'node:fs';\nimport { basename } from 'node:path';\n\ntype Rgb = [number, number, number];\n\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst TRUECOLOR_FG_PREFIX = '\\x1b[38;2;';\nconst XTERM_FG_PREFIX = '\\x1b[38;5;';\n\nconst FALLBACK_PALETTE: Rgb[] = [\n\t[22, 83, 189],\n\t[48, 129, 247],\n\t[93, 171, 255],\n\t[151, 205, 255],\n\t[93, 171, 255],\n\t[48, 129, 247],\n];\n\nconst THEME_GRADIENT_TOKENS: ThemeColor[] = [\n\t'accent',\n\t'borderAccent',\n\t'mdHeading',\n\t'syntaxFunction',\n\t'thinkingHigh',\n\t'mdCode',\n];\n\nconst XTERM_CUBE_VALUES = [0, 95, 135, 175, 215, 255] as const;\nconst XTERM_GRAY_START = 232;\n\nconst TITLE_LINES = [\n\t'███╗ ███╗ ██████╗ ██╗',\n\t'████╗ ████║ ██╗ ██╗ ██╔══██╗ ',\n\t'██╔████╔██║ ╚██╗ ██╔╝ ████╗ ██████╔╝██╗',\n\t'██║╚██╔╝██║ ╚████╔╝ ╚═══╝ ██╔═══╝ ██║',\n\t'██║ ╚═╝ ██║ ╚██╔╝ ██║ ██║',\n\t'╚═╝ ╚═╝ ██╔╝ ╚═╝ ╚═╝',\n] as const;\n\nconst TITLE_WIDTH = Math.max(\n\t...TITLE_LINES.map((line) => line.length),\n);\n\nfunction read_my_pi_version(): string {\n\tconst candidates = [\n\t\tnew URL('../../../package.json', import.meta.url),\n\t\tnew URL('../package.json', import.meta.url),\n\t];\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(\n\t\t\t\treadFileSync(candidate, 'utf-8'),\n\t\t\t);\n\t\t\tconst version = (parsed as { version?: unknown } | null)\n\t\t\t\t?.version;\n\t\t\tif (typeof version === 'string') return version;\n\t\t} catch {\n\t\t\t// Try the next source/distro-relative location.\n\t\t}\n\t}\n\n\treturn 'dev';\n}\n\nconst MY_PI_VERSION = read_my_pi_version();\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn Math.round(a + (b - a) * t);\n}\n\nfunction sample_gradient(position: number, palette: Rgb[]): Rgb {\n\tconst wrapped = ((position % 1) + 1) % 1;\n\tconst scaled = wrapped * palette.length;\n\tconst index = Math.floor(scaled);\n\tconst next_index = (index + 1) % palette.length;\n\tconst t = scaled - index;\n\tconst a = palette[index]!;\n\tconst b = palette[next_index]!;\n\treturn [mix(a[0], b[0], t), mix(a[1], b[1], t), mix(a[2], b[2], t)];\n}\n\nfunction ansi_fg([r, g, b]: Rgb, text: string): string {\n\treturn `\\x1b[38;2;${r};${g};${b}m${text}${RESET}`;\n}\n\nfunction rgb_from_xterm(index: number): Rgb | undefined {\n\tif (index < 0 || index > 255) return undefined;\n\tif (index < 16) return undefined;\n\tif (index >= XTERM_GRAY_START) {\n\t\tconst gray = 8 + (index - XTERM_GRAY_START) * 10;\n\t\treturn [gray, gray, gray];\n\t}\n\n\tconst cube = index - 16;\n\tconst r = XTERM_CUBE_VALUES[Math.floor(cube / 36)]!;\n\tconst g = XTERM_CUBE_VALUES[Math.floor((cube % 36) / 6)]!;\n\tconst b = XTERM_CUBE_VALUES[cube % 6]!;\n\treturn [r, g, b];\n}\n\nfunction ansi_params(\n\tansi: string,\n\tprefix: string,\n): string[] | undefined {\n\tif (!ansi.startsWith(prefix)) return undefined;\n\tconst end = ansi.indexOf('m', prefix.length);\n\tif (end === -1) return undefined;\n\treturn ansi.slice(prefix.length, end).split(';');\n}\n\nfunction rgb_from_ansi(ansi: string): Rgb | undefined {\n\tconst truecolor = ansi_params(ansi, TRUECOLOR_FG_PREFIX);\n\tif (truecolor?.length === 3) {\n\t\treturn [\n\t\t\tNumber(truecolor[0]),\n\t\t\tNumber(truecolor[1]),\n\t\t\tNumber(truecolor[2]),\n\t\t];\n\t}\n\n\tconst xterm = ansi_params(ansi, XTERM_FG_PREFIX);\n\treturn xterm?.length === 1\n\t\t? rgb_from_xterm(Number(xterm[0]))\n\t\t: undefined;\n}\n\nfunction theme_gradient_palette(theme: Theme): Rgb[] {\n\tconst palette: Rgb[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const token of THEME_GRADIENT_TOKENS) {\n\t\tconst rgb = rgb_from_ansi(theme.getFgAnsi(token));\n\t\tif (!rgb) continue;\n\t\tconst key = rgb.join(',');\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tpalette.push(rgb);\n\t}\n\n\treturn palette.length >= 2 ? palette : FALLBACK_PALETTE;\n}\n\nfunction gradient_text(\n\ttext: string,\n\tphase: number,\n\tpalette: Rgb[],\n): string {\n\tconst chars = text.split('');\n\tconst span = Math.max(chars.length - 1, 1);\n\treturn chars\n\t\t.map((char, index) => {\n\t\t\tif (char === ' ') return char;\n\t\t\treturn ansi_fg(\n\t\t\t\tsample_gradient(index / span + phase, palette),\n\t\t\t\tchar,\n\t\t\t);\n\t\t})\n\t\t.join('');\n}\n\nfunction center_line(line: string, width: number): string {\n\tconst clipped =\n\t\tvisibleWidth(line) > width\n\t\t\t? truncateToWidth(line, width, '')\n\t\t\t: line;\n\tconst padding = Math.max(\n\t\t0,\n\t\tMath.floor((width - visibleWidth(clipped)) / 2),\n\t);\n\treturn `${' '.repeat(padding)}${clipped}`;\n}\n\nfunction color_line(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tline: string,\n\tphase: number,\n): string {\n\treturn theme.getColorMode() === 'truecolor'\n\t\t? gradient_text(line, phase, palette)\n\t\t: theme.fg('accent', line);\n}\n\nfunction gradient_or_theme(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tline: string,\n\tphase: number,\n): string {\n\treturn theme.getColorMode() === 'truecolor'\n\t\t? `${BOLD}${gradient_text(line, phase, palette)}${RESET}`\n\t\t: theme.bold(theme.fg('accent', line));\n}\n\nfunction render_brand(\n\ttheme: Theme,\n\tpalette: Rgb[],\n\twidth: number,\n): string {\n\treturn gradient_or_theme(\n\t\ttheme,\n\t\tpalette,\n\t\tcenter_line(`My-Pi v${MY_PI_VERSION}`, width),\n\t\t0.12,\n\t);\n}\n\nfunction render_subtitle(\n\tctx: ExtensionContext,\n\ttheme: Theme,\n\tpalette: Rgb[],\n\tmodel_id: string,\n\twidth: number,\n): string {\n\tconst project = basename(ctx.cwd) || ctx.cwd;\n\tconst subtitle = center_line(`${model_id} · ${project}`, width);\n\treturn gradient_or_theme(theme, palette, subtitle, 0.18);\n}\n\nexport function render_startup_header(\n\tctx: ExtensionContext,\n\ttheme: Theme,\n\twidth: number,\n\tmodel_id = ctx.model?.id ?? 'no model selected',\n): string[] {\n\tif (width < 24) {\n\t\treturn [\n\t\t\tcenter_line(\n\t\t\t\ttheme.bold(theme.fg('accent', `My-Pi v${MY_PI_VERSION}`)),\n\t\t\t\twidth,\n\t\t\t),\n\t\t\tcenter_line(\n\t\t\t\t`${model_id} · ${basename(ctx.cwd) || ctx.cwd}`,\n\t\t\t\twidth,\n\t\t\t),\n\t\t];\n\t}\n\n\tconst palette = theme_gradient_palette(theme);\n\tconst logo = TITLE_LINES.map((line, row) =>\n\t\tcolor_line(\n\t\t\ttheme,\n\t\t\tpalette,\n\t\t\tcenter_line(line.padEnd(TITLE_WIDTH), width),\n\t\t\trow * 0.045,\n\t\t),\n\t);\n\n\treturn [\n\t\t'',\n\t\trender_brand(theme, palette, width),\n\t\t...logo,\n\t\trender_subtitle(ctx, theme, palette, model_id, width),\n\t\t'',\n\t];\n}\n\nexport default function startup_screen_extension(\n\tpi: ExtensionAPI,\n): void {\n\tlet request_render: (() => void) | undefined;\n\tlet current_model_id = 'no model selected';\n\n\tfunction install_header(ctx: ExtensionContext): void {\n\t\tctx.ui.setHeader((tui, theme) => {\n\t\t\trequest_render = () => tui.requestRender();\n\t\t\treturn {\n\t\t\t\tinvalidate() {\n\t\t\t\t\ttui.requestRender();\n\t\t\t\t},\n\t\t\t\trender(width: number) {\n\t\t\t\t\treturn render_startup_header(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\tcurrent_model_id,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t}\n\n\tpi.on('session_start', async (_event, ctx) => {\n\t\tcurrent_model_id = ctx.model?.id ?? 'no model selected';\n\t\tif (!ctx.hasUI) return;\n\t\tinstall_header(ctx);\n\t});\n\n\tpi.on('model_select', (event) => {\n\t\tcurrent_model_id = event.model.id;\n\t\trequest_render?.();\n\t});\n\n\tpi.on('session_shutdown', (_event, ctx) => {\n\t\tif (ctx.hasUI) ctx.ui.setHeader(undefined);\n\t});\n\n\tpi.registerCommand('builtin-header', {\n\t\tdescription: 'Restore the built-in pi startup header',\n\t\thandler: async (_args, ctx) => {\n\t\t\tctx.ui.setHeader(undefined);\n\t\t\tctx.ui.notify('Built-in startup header restored', 'info');\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Text } from "@earendil-works/pi-tui";
|
|
2
|
-
|
|
2
|
+
// src/extensions/turn-timer/index.ts
|
|
3
3
|
const TURN_TIMER_ENTRY = "turn-timer";
|
|
4
4
|
function format_clock(duration_ms) {
|
|
5
5
|
const total_seconds = Math.max(0, Math.floor(duration_ms / 1e3));
|
|
@@ -58,7 +58,6 @@ function turn_timer(pi) {
|
|
|
58
58
|
reset();
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
-
//#endregion
|
|
62
61
|
export { turn_timer as default };
|
|
63
62
|
|
|
64
|
-
//# sourceMappingURL=turn-timer-
|
|
63
|
+
//# sourceMappingURL=turn-timer-mowT6nwv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-timer-
|
|
1
|
+
{"version":3,"file":"turn-timer-mowT6nwv.js","names":[],"sources":["../src/extensions/turn-timer/index.ts"],"sourcesContent":["import type {\n\tExtensionAPI,\n\tExtensionContext,\n} from '@earendil-works/pi-coding-agent';\nimport { Text } from '@earendil-works/pi-tui';\n\nexport const TURN_TIMER_ENTRY = 'turn-timer';\nexport interface TurnTimerEntry {\n\tduration_ms: number;\n\tcompleted_at: string;\n}\n\nexport function format_clock(duration_ms: number): string {\n\tconst total_seconds = Math.max(0, Math.floor(duration_ms / 1_000));\n\tconst hours = Math.floor(total_seconds / 3_600);\n\tconst minutes = Math.floor((total_seconds % 3_600) / 60);\n\tconst seconds = total_seconds % 60;\n\n\treturn hours > 0\n\t\t? `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`\n\t\t: `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n}\n\nexport function format_duration(duration_ms: number): string {\n\tif (duration_ms < 1_000)\n\t\treturn `${Math.max(0, Math.round(duration_ms))}ms`;\n\tif (duration_ms < 60_000)\n\t\treturn `${(duration_ms / 1_000).toFixed(1)}s`;\n\treturn format_clock(duration_ms);\n}\n\nexport default function turn_timer(pi: ExtensionAPI): void {\n\tlet started_at: number | undefined;\n\tlet refresh_timer: NodeJS.Timeout | undefined;\n\tlet active_context: ExtensionContext | undefined;\n\n\tconst clear_timer = (): void => {\n\t\tif (refresh_timer) clearInterval(refresh_timer);\n\t\trefresh_timer = undefined;\n\t};\n\n\tconst render_timer = (): void => {\n\t\tif (started_at === undefined || !active_context) return;\n\t\tconst timer = active_context.ui.theme.fg(\n\t\t\t'success',\n\t\t\tformat_clock(Date.now() - started_at),\n\t\t);\n\t\tactive_context.ui.setWorkingMessage(`Working... ${timer}`);\n\t};\n\n\tconst reset = (): void => {\n\t\tclear_timer();\n\t\tif (active_context?.mode === 'tui') {\n\t\t\tactive_context.ui.setWorkingMessage(undefined);\n\t\t}\n\t\tstarted_at = undefined;\n\t\tactive_context = undefined;\n\t};\n\n\tpi.registerEntryRenderer<TurnTimerEntry>(\n\t\tTURN_TIMER_ENTRY,\n\t\t(entry, _options, theme) => {\n\t\t\tif (\n\t\t\t\t!entry.data ||\n\t\t\t\ttypeof entry.data.duration_ms !== 'number' ||\n\t\t\t\t!Number.isFinite(entry.data.duration_ms)\n\t\t\t) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn new Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t'success',\n\t\t\t\t\t`⏱ Completed in ${format_duration(entry.data.duration_ms)}`,\n\t\t\t\t),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t);\n\t\t},\n\t);\n\n\tpi.on('agent_start', async (_event, ctx) => {\n\t\tif (started_at !== undefined) return;\n\t\tstarted_at = Date.now();\n\t\tactive_context = ctx;\n\n\t\tif (ctx.mode !== 'tui') return;\n\t\trender_timer();\n\t\trefresh_timer = setInterval(render_timer, 1_000);\n\t\trefresh_timer.unref?.();\n\t});\n\n\tpi.on('agent_settled', async () => {\n\t\tif (started_at === undefined) return;\n\t\tconst duration_ms = Date.now() - started_at;\n\t\treset();\n\t\tpi.appendEntry<TurnTimerEntry>(TURN_TIMER_ENTRY, {\n\t\t\tduration_ms,\n\t\t\tcompleted_at: new Date().toISOString(),\n\t\t});\n\t});\n\n\tpi.on('session_shutdown', async () => {\n\t\treset();\n\t});\n}\n"],"mappings":";;AAMA,MAAa,mBAAmB;AAMhC,SAAgB,aAAa,aAA6B;CACzD,MAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,GAAK,CAAC;CACjE,MAAM,QAAQ,KAAK,MAAM,gBAAgB,IAAK;CAC9C,MAAM,UAAU,KAAK,MAAO,gBAAgB,OAAS,EAAE;CACvD,MAAM,UAAU,gBAAgB;CAEhC,OAAO,QAAQ,IACZ,GAAG,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,QAAQ,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,QAAQ,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,MACjH,GAAG,QAAQ,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,QAAQ,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG;AAChF;AAEA,SAAgB,gBAAgB,aAA6B;CAC5D,IAAI,cAAc,KACjB,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC,EAAE;CAChD,IAAI,cAAc,KACjB,OAAO,IAAI,cAAc,IAAA,CAAO,QAAQ,CAAC,EAAE;CAC5C,OAAO,aAAa,WAAW;AAChC;AAEA,SAAwB,WAAW,IAAwB;CAC1D,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,oBAA0B;EAC/B,IAAI,eAAe,cAAc,aAAa;EAC9C,gBAAgB,KAAA;CACjB;CAEA,MAAM,qBAA2B;EAChC,IAAI,eAAe,KAAA,KAAa,CAAC,gBAAgB;EACjD,MAAM,QAAQ,eAAe,GAAG,MAAM,GACrC,WACA,aAAa,KAAK,IAAI,IAAI,UAAU,CACrC;EACA,eAAe,GAAG,kBAAkB,cAAc,OAAO;CAC1D;CAEA,MAAM,cAAoB;EACzB,YAAY;EACZ,IAAI,gBAAgB,SAAS,OAC5B,eAAe,GAAG,kBAAkB,KAAA,CAAS;EAE9C,aAAa,KAAA;EACb,iBAAiB,KAAA;CAClB;CAEA,GAAG,sBACF,mBACC,OAAO,UAAU,UAAU;EAC3B,IACC,CAAC,MAAM,QACP,OAAO,MAAM,KAAK,gBAAgB,YAClC,CAAC,OAAO,SAAS,MAAM,KAAK,WAAW,GAEvC;EAED,OAAO,IAAI,KACV,MAAM,GACL,WACA,kBAAkB,gBAAgB,MAAM,KAAK,WAAW,GACzD,GACA,GACA,CACD;CACD,CACD;CAEA,GAAG,GAAG,eAAe,OAAO,QAAQ,QAAQ;EAC3C,IAAI,eAAe,KAAA,GAAW;EAC9B,aAAa,KAAK,IAAI;EACtB,iBAAiB;EAEjB,IAAI,IAAI,SAAS,OAAO;EACxB,aAAa;EACb,gBAAgB,YAAY,cAAc,GAAK;EAC/C,cAAc,QAAQ;CACvB,CAAC;CAED,GAAG,GAAG,iBAAiB,YAAY;EAClC,IAAI,eAAe,KAAA,GAAW;EAC9B,MAAM,cAAc,KAAK,IAAI,IAAI;EACjC,MAAM;EACN,GAAG,YAA4B,kBAAkB;GAChD;GACA,+BAAc,IAAI,KAAK,EAAA,CAAE,YAAY;EACtC,CAAC;CACF,CAAC;CAED,GAAG,GAAG,oBAAoB,YAAY;EACrC,MAAM;CACP,CAAC;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createProvider } from "@earendil-works/pi-ai";
|
|
2
2
|
import { anthropicMessagesApi } from "@earendil-works/pi-ai/api/anthropic-messages.lazy";
|
|
3
|
-
|
|
3
|
+
// src/extensions/umans-provider/index.ts
|
|
4
4
|
const DEFAULT_BASE_URL = "https://api.code.umans.ai";
|
|
5
5
|
const API_KEY_ENV = "UMANS_API_KEY";
|
|
6
6
|
const USER_AGENT = "my-pi-umans-provider/0.1.0";
|
|
@@ -301,7 +301,6 @@ const extension = (pi) => {
|
|
|
301
301
|
if (process.env.UMANS_DISABLE === "1") return;
|
|
302
302
|
pi.registerProvider(create_umans_provider());
|
|
303
303
|
};
|
|
304
|
-
//#endregion
|
|
305
304
|
export { extension as default };
|
|
306
305
|
|
|
307
|
-
//# sourceMappingURL=umans-provider-
|
|
306
|
+
//# sourceMappingURL=umans-provider-DIupQTRK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"umans-provider-C2UJ4qkO.js","names":[],"sources":["../src/extensions/umans-provider/index.ts"],"sourcesContent":["import {\n\tcreateProvider,\n\ttype ApiKeyAuth,\n\ttype AuthInteraction,\n\ttype Credential,\n\ttype OAuthAuth,\n\ttype OAuthCredential,\n\ttype Provider,\n} from '@earendil-works/pi-ai';\nimport { anthropicMessagesApi } from '@earendil-works/pi-ai/api/anthropic-messages.lazy';\nimport type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nconst DEFAULT_BASE_URL = 'https://api.code.umans.ai';\nconst API_KEY_ENV = 'UMANS_API_KEY';\nconst USER_AGENT = 'my-pi-umans-provider/0.1.0';\n\ninterface ReasoningInfo {\n\tsupported: boolean;\n\tcan_disable: boolean;\n\tlevels: string[];\n\tdefault_level: string;\n}\n\ninterface ModelCapabilities {\n\tmax_completion_tokens?: number;\n\trecommended_max_tokens?: number;\n\tcontext_window?: number;\n\tsupports_vision?: boolean | 'via-handoff';\n\tsupports_tools?: boolean;\n\treasoning?: ReasoningInfo;\n}\n\ninterface UmansModelInfo {\n\tname: string;\n\tdisplay_name?: string;\n\tdeprecation?: unknown;\n\tcapabilities: ModelCapabilities;\n}\n\nexport const STATIC_UMANS_CATALOG: Record<string, UmansModelInfo> = {\n\t'umans-kimi-k2.6': {\n\t\tname: 'umans-kimi-k2.6',\n\t\tdisplay_name: 'Umans Kimi K2.6',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-kimi-k2.7': {\n\t\tname: 'umans-kimi-k2.7',\n\t\tdisplay_name: 'Umans Kimi K2.7 Code',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-glm-5.2': {\n\t\tname: 'umans-glm-5.2',\n\t\tdisplay_name: 'Umans GLM 5.2',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 131072,\n\t\t\trecommended_max_tokens: 131071,\n\t\t\tcontext_window: 405504,\n\t\t\tsupports_vision: 'via-handoff',\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-coder': {\n\t\tname: 'umans-coder',\n\t\tdisplay_name: 'Umans Coder',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-flash': {\n\t\tname: 'umans-flash',\n\t\tdisplay_name: 'Umans Flash',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-qwen3.6-35b-a3b': {\n\t\tname: 'umans-qwen3.6-35b-a3b',\n\t\tdisplay_name: 'Umans Qwen3.6 35B A3B',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n};\n\nfunction safe_max_tokens(recommended?: number, cap?: number): number {\n\tlet value =\n\t\ttypeof recommended === 'number' && recommended > 0\n\t\t\t? recommended\n\t\t\t: 32768;\n\tif (typeof cap === 'number' && cap > 0)\n\t\tvalue = Math.min(value, cap - 1);\n\treturn Math.max(value, 1);\n}\n\nfunction is_record(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\t!!value && typeof value === 'object' && !Array.isArray(value)\n\t);\n}\n\nexport function normalize_umans_catalog(\n\tvalue: unknown,\n): Record<string, UmansModelInfo> {\n\tconst source =\n\t\tis_record(value) && is_record(value.data) ? value.data : value;\n\tif (!is_record(source)) return {};\n\n\tconst catalog: Record<string, UmansModelInfo> = {};\n\tfor (const [id, info] of Object.entries(source)) {\n\t\tif (!is_record(info)) continue;\n\t\tconst capabilities = is_record(info.capabilities)\n\t\t\t? info.capabilities\n\t\t\t: {};\n\t\tcatalog[id] = {\n\t\t\tname: typeof info.name === 'string' ? info.name : id,\n\t\t\tdisplay_name:\n\t\t\t\ttypeof info.display_name === 'string'\n\t\t\t\t\t? info.display_name\n\t\t\t\t\t: id,\n\t\t\tdeprecation: info.deprecation,\n\t\t\tcapabilities: capabilities as ModelCapabilities,\n\t\t};\n\t}\n\treturn catalog;\n}\n\nexport async function fetch_umans_catalog(\n\tbase_url: string,\n\tapi_key?: string,\n\tsignal?: AbortSignal,\n): Promise<Record<string, UmansModelInfo>> {\n\tconst headers: Record<string, string> = {\n\t\t'user-agent': USER_AGENT,\n\t};\n\tif (api_key) headers.authorization = `Bearer ${api_key}`;\n\n\tconst response = await fetch(\n\t\t`${base_url.replace(/\\/$/, '')}/v1/models/info`,\n\t\t{ headers, signal },\n\t);\n\tif (!response.ok) throw new Error(`HTTP ${response.status}`);\n\treturn normalize_umans_catalog(await response.json());\n}\n\nexport function to_pi_models(\n\tcatalog: Record<string, UmansModelInfo>,\n\tbase_url = DEFAULT_BASE_URL,\n) {\n\treturn Object.entries(catalog)\n\t\t.filter(([, info]) => !info.deprecation)\n\t\t.map(([id, info]) => {\n\t\t\tconst capabilities = info.capabilities ?? {};\n\t\t\tconst input: ('text' | 'image')[] = capabilities.supports_vision\n\t\t\t\t? ['text', 'image']\n\t\t\t\t: ['text'];\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tname: info.display_name ?? id,\n\t\t\t\tapi: 'anthropic-messages' as const,\n\t\t\t\tprovider: 'umans',\n\t\t\t\tbaseUrl: base_url,\n\t\t\t\tmaxTokens: safe_max_tokens(\n\t\t\t\t\tcapabilities.recommended_max_tokens,\n\t\t\t\t\tcapabilities.max_completion_tokens,\n\t\t\t\t),\n\t\t\t\tcontextWindow: capabilities.context_window ?? 262144,\n\t\t\t\treasoning: capabilities.reasoning?.supported === true,\n\t\t\t\tinput,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\tsupportsTools: capabilities.supports_tools !== false,\n\t\t\t};\n\t\t});\n}\n\nasync function prompt_for_api_key(\n\tinteraction: AuthInteraction,\n): Promise<string> {\n\tconst api_key = await interaction.prompt({\n\t\ttype: 'secret',\n\t\tmessage: 'Enter your Umans API key:',\n\t});\n\tconst key = api_key.trim();\n\tif (!key) throw new Error('Umans API key is required');\n\treturn key;\n}\n\nfunction bearer_auth(key: string) {\n\treturn {\n\t\tauth: { headers: { authorization: `Bearer ${key}` } },\n\t};\n}\n\nexport function create_umans_api_key_auth(\n\tenv: NodeJS.ProcessEnv = process.env,\n): ApiKeyAuth {\n\treturn {\n\t\tname: 'Umans API key',\n\t\tasync login(interaction) {\n\t\t\treturn {\n\t\t\t\ttype: 'api_key',\n\t\t\t\tkey: await prompt_for_api_key(interaction),\n\t\t\t};\n\t\t},\n\t\tasync check({ credential }) {\n\t\t\tif (credential?.key)\n\t\t\t\treturn { type: 'api_key', source: 'stored API key' };\n\t\t\tif (env[API_KEY_ENV]?.trim())\n\t\t\t\treturn { type: 'api_key', source: API_KEY_ENV };\n\t\t\treturn undefined;\n\t\t},\n\t\tasync resolve({ credential }) {\n\t\t\tconst stored_key = credential?.key?.trim();\n\t\t\tif (stored_key)\n\t\t\t\treturn {\n\t\t\t\t\t...bearer_auth(stored_key),\n\t\t\t\t\tsource: 'stored API key',\n\t\t\t\t};\n\t\t\tconst env_key = env[API_KEY_ENV]?.trim();\n\t\t\treturn env_key\n\t\t\t\t? { ...bearer_auth(env_key), source: API_KEY_ENV }\n\t\t\t\t: undefined;\n\t\t},\n\t};\n}\n\nfunction create_legacy_umans_oauth(): OAuthAuth {\n\treturn {\n\t\tname: 'Legacy Umans credential',\n\t\tloginLabel: 'Enter Umans API key (legacy credential)',\n\t\tasync login(interaction): Promise<OAuthCredential> {\n\t\t\tconst key = await prompt_for_api_key(interaction);\n\t\t\treturn {\n\t\t\t\ttype: 'oauth',\n\t\t\t\trefresh: key,\n\t\t\t\taccess: key,\n\t\t\t\texpires: Date.now() + 100 * 365 * 24 * 60 * 60 * 1000,\n\t\t\t};\n\t\t},\n\t\trefresh: (credential) => Promise.resolve(credential),\n\t\ttoAuth: async (credential) => bearer_auth(credential.access).auth,\n\t};\n}\n\nfunction credential_key(\n\tcredential: Credential | undefined,\n\tenv: NodeJS.ProcessEnv,\n): string | undefined {\n\tif (credential?.type === 'api_key') return credential.key?.trim();\n\tif (credential?.type === 'oauth') return credential.access.trim();\n\treturn env[API_KEY_ENV]?.trim() || undefined;\n}\n\nexport interface CreateUmansProviderOptions {\n\tbase_url?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tfetch_catalog?: typeof fetch_umans_catalog;\n}\n\nexport function create_umans_provider(\n\toptions: CreateUmansProviderOptions = {},\n): Provider<'anthropic-messages'> {\n\tconst env = options.env ?? process.env;\n\tconst base_url =\n\t\toptions.base_url?.trim() ||\n\t\tenv.UMANS_BASE_URL?.trim() ||\n\t\tDEFAULT_BASE_URL;\n\tconst fetch_catalog = options.fetch_catalog ?? fetch_umans_catalog;\n\treturn createProvider({\n\t\tid: 'umans',\n\t\tname: 'Umans',\n\t\tbaseUrl: base_url,\n\t\tauth: {\n\t\t\tapiKey: create_umans_api_key_auth(env),\n\t\t\toauth: create_legacy_umans_oauth(),\n\t\t},\n\t\tmodels: to_pi_models(STATIC_UMANS_CATALOG, base_url),\n\t\tasync fetchModels(context) {\n\t\t\tconst catalog = await fetch_catalog(\n\t\t\t\tbase_url,\n\t\t\t\tcredential_key(context.credential, env),\n\t\t\t\tcontext.signal,\n\t\t\t);\n\t\t\treturn to_pi_models(catalog, base_url);\n\t\t},\n\t\tapi: anthropicMessagesApi(),\n\t});\n}\n\nconst extension: ExtensionFactory = (pi) => {\n\tif (process.env.UMANS_DISABLE === '1') return;\n\tpi.registerProvider(create_umans_provider());\n};\n\nexport default extension;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"umans-provider-DIupQTRK.js","names":[],"sources":["../src/extensions/umans-provider/index.ts"],"sourcesContent":["import {\n\tcreateProvider,\n\ttype ApiKeyAuth,\n\ttype AuthInteraction,\n\ttype Credential,\n\ttype OAuthAuth,\n\ttype OAuthCredential,\n\ttype Provider,\n} from '@earendil-works/pi-ai';\nimport { anthropicMessagesApi } from '@earendil-works/pi-ai/api/anthropic-messages.lazy';\nimport type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nconst DEFAULT_BASE_URL = 'https://api.code.umans.ai';\nconst API_KEY_ENV = 'UMANS_API_KEY';\nconst USER_AGENT = 'my-pi-umans-provider/0.1.0';\n\ninterface ReasoningInfo {\n\tsupported: boolean;\n\tcan_disable: boolean;\n\tlevels: string[];\n\tdefault_level: string;\n}\n\ninterface ModelCapabilities {\n\tmax_completion_tokens?: number;\n\trecommended_max_tokens?: number;\n\tcontext_window?: number;\n\tsupports_vision?: boolean | 'via-handoff';\n\tsupports_tools?: boolean;\n\treasoning?: ReasoningInfo;\n}\n\ninterface UmansModelInfo {\n\tname: string;\n\tdisplay_name?: string;\n\tdeprecation?: unknown;\n\tcapabilities: ModelCapabilities;\n}\n\nexport const STATIC_UMANS_CATALOG: Record<string, UmansModelInfo> = {\n\t'umans-kimi-k2.6': {\n\t\tname: 'umans-kimi-k2.6',\n\t\tdisplay_name: 'Umans Kimi K2.6',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-kimi-k2.7': {\n\t\tname: 'umans-kimi-k2.7',\n\t\tdisplay_name: 'Umans Kimi K2.7 Code',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-glm-5.2': {\n\t\tname: 'umans-glm-5.2',\n\t\tdisplay_name: 'Umans GLM 5.2',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 131072,\n\t\t\trecommended_max_tokens: 131071,\n\t\t\tcontext_window: 405504,\n\t\t\tsupports_vision: 'via-handoff',\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-coder': {\n\t\tname: 'umans-coder',\n\t\tdisplay_name: 'Umans Coder',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-flash': {\n\t\tname: 'umans-flash',\n\t\tdisplay_name: 'Umans Flash',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-qwen3.6-35b-a3b': {\n\t\tname: 'umans-qwen3.6-35b-a3b',\n\t\tdisplay_name: 'Umans Qwen3.6 35B A3B',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n};\n\nfunction safe_max_tokens(recommended?: number, cap?: number): number {\n\tlet value =\n\t\ttypeof recommended === 'number' && recommended > 0\n\t\t\t? recommended\n\t\t\t: 32768;\n\tif (typeof cap === 'number' && cap > 0)\n\t\tvalue = Math.min(value, cap - 1);\n\treturn Math.max(value, 1);\n}\n\nfunction is_record(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\t!!value && typeof value === 'object' && !Array.isArray(value)\n\t);\n}\n\nexport function normalize_umans_catalog(\n\tvalue: unknown,\n): Record<string, UmansModelInfo> {\n\tconst source =\n\t\tis_record(value) && is_record(value.data) ? value.data : value;\n\tif (!is_record(source)) return {};\n\n\tconst catalog: Record<string, UmansModelInfo> = {};\n\tfor (const [id, info] of Object.entries(source)) {\n\t\tif (!is_record(info)) continue;\n\t\tconst capabilities = is_record(info.capabilities)\n\t\t\t? info.capabilities\n\t\t\t: {};\n\t\tcatalog[id] = {\n\t\t\tname: typeof info.name === 'string' ? info.name : id,\n\t\t\tdisplay_name:\n\t\t\t\ttypeof info.display_name === 'string'\n\t\t\t\t\t? info.display_name\n\t\t\t\t\t: id,\n\t\t\tdeprecation: info.deprecation,\n\t\t\tcapabilities: capabilities as ModelCapabilities,\n\t\t};\n\t}\n\treturn catalog;\n}\n\nexport async function fetch_umans_catalog(\n\tbase_url: string,\n\tapi_key?: string,\n\tsignal?: AbortSignal,\n): Promise<Record<string, UmansModelInfo>> {\n\tconst headers: Record<string, string> = {\n\t\t'user-agent': USER_AGENT,\n\t};\n\tif (api_key) headers.authorization = `Bearer ${api_key}`;\n\n\tconst response = await fetch(\n\t\t`${base_url.replace(/\\/$/, '')}/v1/models/info`,\n\t\t{ headers, signal },\n\t);\n\tif (!response.ok) throw new Error(`HTTP ${response.status}`);\n\treturn normalize_umans_catalog(await response.json());\n}\n\nexport function to_pi_models(\n\tcatalog: Record<string, UmansModelInfo>,\n\tbase_url = DEFAULT_BASE_URL,\n) {\n\treturn Object.entries(catalog)\n\t\t.filter(([, info]) => !info.deprecation)\n\t\t.map(([id, info]) => {\n\t\t\tconst capabilities = info.capabilities ?? {};\n\t\t\tconst input: ('text' | 'image')[] = capabilities.supports_vision\n\t\t\t\t? ['text', 'image']\n\t\t\t\t: ['text'];\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tname: info.display_name ?? id,\n\t\t\t\tapi: 'anthropic-messages' as const,\n\t\t\t\tprovider: 'umans',\n\t\t\t\tbaseUrl: base_url,\n\t\t\t\tmaxTokens: safe_max_tokens(\n\t\t\t\t\tcapabilities.recommended_max_tokens,\n\t\t\t\t\tcapabilities.max_completion_tokens,\n\t\t\t\t),\n\t\t\t\tcontextWindow: capabilities.context_window ?? 262144,\n\t\t\t\treasoning: capabilities.reasoning?.supported === true,\n\t\t\t\tinput,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\tsupportsTools: capabilities.supports_tools !== false,\n\t\t\t};\n\t\t});\n}\n\nasync function prompt_for_api_key(\n\tinteraction: AuthInteraction,\n): Promise<string> {\n\tconst api_key = await interaction.prompt({\n\t\ttype: 'secret',\n\t\tmessage: 'Enter your Umans API key:',\n\t});\n\tconst key = api_key.trim();\n\tif (!key) throw new Error('Umans API key is required');\n\treturn key;\n}\n\nfunction bearer_auth(key: string) {\n\treturn {\n\t\tauth: { headers: { authorization: `Bearer ${key}` } },\n\t};\n}\n\nexport function create_umans_api_key_auth(\n\tenv: NodeJS.ProcessEnv = process.env,\n): ApiKeyAuth {\n\treturn {\n\t\tname: 'Umans API key',\n\t\tasync login(interaction) {\n\t\t\treturn {\n\t\t\t\ttype: 'api_key',\n\t\t\t\tkey: await prompt_for_api_key(interaction),\n\t\t\t};\n\t\t},\n\t\tasync check({ credential }) {\n\t\t\tif (credential?.key)\n\t\t\t\treturn { type: 'api_key', source: 'stored API key' };\n\t\t\tif (env[API_KEY_ENV]?.trim())\n\t\t\t\treturn { type: 'api_key', source: API_KEY_ENV };\n\t\t\treturn undefined;\n\t\t},\n\t\tasync resolve({ credential }) {\n\t\t\tconst stored_key = credential?.key?.trim();\n\t\t\tif (stored_key)\n\t\t\t\treturn {\n\t\t\t\t\t...bearer_auth(stored_key),\n\t\t\t\t\tsource: 'stored API key',\n\t\t\t\t};\n\t\t\tconst env_key = env[API_KEY_ENV]?.trim();\n\t\t\treturn env_key\n\t\t\t\t? { ...bearer_auth(env_key), source: API_KEY_ENV }\n\t\t\t\t: undefined;\n\t\t},\n\t};\n}\n\nfunction create_legacy_umans_oauth(): OAuthAuth {\n\treturn {\n\t\tname: 'Legacy Umans credential',\n\t\tloginLabel: 'Enter Umans API key (legacy credential)',\n\t\tasync login(interaction): Promise<OAuthCredential> {\n\t\t\tconst key = await prompt_for_api_key(interaction);\n\t\t\treturn {\n\t\t\t\ttype: 'oauth',\n\t\t\t\trefresh: key,\n\t\t\t\taccess: key,\n\t\t\t\texpires: Date.now() + 100 * 365 * 24 * 60 * 60 * 1000,\n\t\t\t};\n\t\t},\n\t\trefresh: (credential) => Promise.resolve(credential),\n\t\ttoAuth: async (credential) => bearer_auth(credential.access).auth,\n\t};\n}\n\nfunction credential_key(\n\tcredential: Credential | undefined,\n\tenv: NodeJS.ProcessEnv,\n): string | undefined {\n\tif (credential?.type === 'api_key') return credential.key?.trim();\n\tif (credential?.type === 'oauth') return credential.access.trim();\n\treturn env[API_KEY_ENV]?.trim() || undefined;\n}\n\nexport interface CreateUmansProviderOptions {\n\tbase_url?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tfetch_catalog?: typeof fetch_umans_catalog;\n}\n\nexport function create_umans_provider(\n\toptions: CreateUmansProviderOptions = {},\n): Provider<'anthropic-messages'> {\n\tconst env = options.env ?? process.env;\n\tconst base_url =\n\t\toptions.base_url?.trim() ||\n\t\tenv.UMANS_BASE_URL?.trim() ||\n\t\tDEFAULT_BASE_URL;\n\tconst fetch_catalog = options.fetch_catalog ?? fetch_umans_catalog;\n\treturn createProvider({\n\t\tid: 'umans',\n\t\tname: 'Umans',\n\t\tbaseUrl: base_url,\n\t\tauth: {\n\t\t\tapiKey: create_umans_api_key_auth(env),\n\t\t\toauth: create_legacy_umans_oauth(),\n\t\t},\n\t\tmodels: to_pi_models(STATIC_UMANS_CATALOG, base_url),\n\t\tasync fetchModels(context) {\n\t\t\tconst catalog = await fetch_catalog(\n\t\t\t\tbase_url,\n\t\t\t\tcredential_key(context.credential, env),\n\t\t\t\tcontext.signal,\n\t\t\t);\n\t\t\treturn to_pi_models(catalog, base_url);\n\t\t},\n\t\tapi: anthropicMessagesApi(),\n\t});\n}\n\nconst extension: ExtensionFactory = (pi) => {\n\tif (process.env.UMANS_DISABLE === '1') return;\n\tpi.registerProvider(create_umans_provider());\n};\n\nexport default extension;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-pi",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Composable pi coding agent with MCP, LSP, prompt presets, and local eval telemetry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@earendil-works/pi-ai": "1.
|
|
47
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
48
|
-
"@earendil-works/pi-tui": "1.
|
|
46
|
+
"@earendil-works/pi-ai": "1.4.0",
|
|
47
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
48
|
+
"@earendil-works/pi-tui": "1.4.0",
|
|
49
49
|
"@spences10/pi-project-trust": "0.0.19",
|
|
50
50
|
"@spences10/pi-settings": "0.0.3",
|
|
51
51
|
"@spences10/pi-themes": "0.0.10",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@changesets/cli": "^3.0.0",
|
|
57
57
|
"@resvg/resvg-js": "^2.6.2",
|
|
58
|
-
"@types/node": "^
|
|
59
|
-
"@vitest/coverage-v8": "5.0.
|
|
60
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@1.
|
|
61
|
-
"vite-plus": "1.
|
|
62
|
-
"vitest": "5.0.
|
|
58
|
+
"@types/node": "^26.0.0",
|
|
59
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
60
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
|
|
61
|
+
"vite-plus": "1.4.0",
|
|
62
|
+
"vitest": "5.0.5"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
65
|
"@spences10/pi-child-env": "0.1.10",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@spences10/pi-lsp": "0.0.49",
|
|
76
76
|
"@spences10/pi-mcp": "0.0.60",
|
|
77
77
|
"@spences10/pi-nopeek": "0.0.16",
|
|
78
|
-
"@spences10/pi-observability": "0.0.
|
|
78
|
+
"@spences10/pi-observability": "0.0.24",
|
|
79
79
|
"@spences10/pi-omnisearch": "0.0.15",
|
|
80
80
|
"@spences10/pi-recall": "0.0.16",
|
|
81
81
|
"@spences10/pi-redact": "0.0.15",
|