@docyrus/docyrus 0.0.64 → 0.0.65

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.
@@ -1,6 +1,6 @@
1
1
  import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@mariozechner/pi-coding-agent";
2
2
  import type { McpExtensionState } from "./state.js";
3
- import { Type } from "@sinclair/typebox";
3
+ import { Type } from "typebox";
4
4
  import { showStatus, showTools, reconnectServers, authenticateServer, openMcpPanel } from "./commands.js";
5
5
  import { loadMcpConfig } from "./config.js";
6
6
  import { buildProxyDescription, createDirectToolExecutor, resolveDirectTools } from "./direct-tools.js";
@@ -65,7 +65,7 @@
65
65
  "dependencies": {
66
66
  "@modelcontextprotocol/ext-apps": "^1.2.2",
67
67
  "@modelcontextprotocol/sdk": "^1.25.1",
68
- "@sinclair/typebox": "^0.32.0",
68
+ "typebox": "^1.1.24",
69
69
  "zod": "^3.25.0 || ^4.0.0"
70
70
  },
71
71
  "devDependencies": {
@@ -1,5 +1,9 @@
1
- import type { ExtensionAPI, ExtensionContext, ModelSelectEvent, ThinkingLevel } from "@mariozechner/pi-coding-agent";
1
+ import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
2
2
  import { CustomEditor, ModelSelectorComponent, SettingsManager } from "@mariozechner/pi-coding-agent";
3
+
4
+ // Mirrors @mariozechner/pi-agent-core's ThinkingLevel (including "off"), defined locally so this
5
+ // extension can be loaded by pi without pulling an additional direct dep. Keep in sync with pi-agent-core.
6
+ type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
3
7
  import path from "node:path";
4
8
  import os from "node:os";
5
9
  import fs from "node:fs/promises";
@@ -1148,13 +1152,28 @@ function setEditor(pi: ExtensionAPI, ctx: ExtensionContext, history: PromptEntry
1148
1152
  requestEditorRender = () => editor.requestRenderNow();
1149
1153
  editor.modeLabelProvider = () => runtime.currentMode;
1150
1154
  // Keep the mode label color stable (match footer/status bar).
1151
- editor.modeLabelColor = (text: string) => ctx.ui.theme.fg("dim", text);
1155
+ // ctx can go stale after session replacement or reload; swallow the stale
1156
+ // assertion in the render-path callbacks so the last TUI frame doesn't crash.
1157
+ editor.modeLabelColor = (text: string) => {
1158
+ try {
1159
+ return ctx.ui.theme.fg("dim", text);
1160
+ } catch {
1161
+ return text;
1162
+ }
1163
+ };
1152
1164
  const borderColor = (text: string) => {
1153
- const isBashMode = editor.getText().trimStart().startsWith("!");
1154
- if (isBashMode) {
1155
- return ctx.ui.theme.getBashModeBorderColor()(text);
1165
+ // ctx can go stale after session replacement or reload; a final TUI render
1166
+ // can still fire from timers and calls into ctx.ui.* throw. Fall back to
1167
+ // the raw text instead of crashing the editor on the way out.
1168
+ try {
1169
+ const isBashMode = editor.getText().trimStart().startsWith("!");
1170
+ if (isBashMode) {
1171
+ return ctx.ui.theme.getBashModeBorderColor()(text);
1172
+ }
1173
+ return getModeBorderColor(ctx, pi, runtime.currentMode)(text);
1174
+ } catch {
1175
+ return text;
1156
1176
  }
1157
- return getModeBorderColor(ctx, pi, runtime.currentMode)(text);
1158
1177
  };
1159
1178
 
1160
1179
  editor.borderColor = borderColor;
@@ -1267,7 +1286,7 @@ export default function(pi: ExtensionAPI) {
1267
1286
  applyEditor(pi, ctx);
1268
1287
  });
1269
1288
 
1270
- pi.on("model_select", async(event: ModelSelectEvent, ctx) => {
1289
+ pi.on("model_select", async(event, ctx) => {
1271
1290
  // Always track the last observed model for overlay/store correctness.
1272
1291
  lastObservedModel = { provider: event.model.provider, modelId: event.model.id };
1273
1292
 
@@ -31,7 +31,7 @@
31
31
  */
32
32
  import { DynamicBorder, copyToClipboard, getMarkdownTheme, keyHint, type ExtensionAPI, type ExtensionContext, type Theme } from "@mariozechner/pi-coding-agent";
33
33
  import { StringEnum } from "@mariozechner/pi-ai";
34
- import { Type } from "@sinclair/typebox";
34
+ import { Type } from "typebox";
35
35
  import path from "node:path";
36
36
  import fs from "node:fs/promises";
37
37
  import { existsSync, readFileSync, readdirSync } from "node:fs";
package/server-loader.js CHANGED
@@ -18792,6 +18792,14 @@ var AUTH_DIR_PATH = (0, import_node_path3.join)((0, import_node_os.homedir)(), D
18792
18792
  var AUTH_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "auth.json");
18793
18793
  var CONFIG_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "config.json");
18794
18794
  var TENANT_OPENAPI_ROOT_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "tenans");
18795
+ var DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH = (0, import_node_path3.join)(
18796
+ AUTH_DIR_PATH,
18797
+ DOCYRUS_PI_DIR_NAME,
18798
+ DOCYRUS_PI_AGENT_DIR_NAME
18799
+ );
18800
+ function getDocyrusPiAgentGlobalRootPath() {
18801
+ return DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH;
18802
+ }
18795
18803
  var DEFAULT_ENVIRONMENT_ID = "live";
18796
18804
  var DEFAULT_ENVIRONMENTS = [
18797
18805
  {
@@ -18815,9 +18823,6 @@ var DEFAULT_ENVIRONMENTS = [
18815
18823
  apiBaseUrl: "https://localhost:3366"
18816
18824
  }
18817
18825
  ];
18818
- function resolveDocyrusPiAgentRootPath(settingsRootPath) {
18819
- return (0, import_node_path3.join)(settingsRootPath, DOCYRUS_PI_DIR_NAME, DOCYRUS_PI_AGENT_DIR_NAME);
18820
- }
18821
18826
  function normalizeApiBaseUrl(apiBaseUrl) {
18822
18827
  const trimmed = apiBaseUrl.trim();
18823
18828
  if (!trimmed) {
@@ -41021,6 +41026,60 @@ function createCustomOpenAiProviderConfig(params) {
41021
41026
  ]
41022
41027
  };
41023
41028
  }
41029
+ var DEEPSEEK_BASE_URL = "https://api.deepseek.com";
41030
+ var DEEPSEEK_MODELS = [
41031
+ {
41032
+ id: "deepseek-v4-flash",
41033
+ name: "DeepSeek V4 Flash",
41034
+ cost: {
41035
+ input: 0.14,
41036
+ output: 0.28,
41037
+ cacheRead: 0.028,
41038
+ cacheWrite: 0.14
41039
+ }
41040
+ },
41041
+ {
41042
+ id: "deepseek-v4-pro",
41043
+ name: "DeepSeek V4 Pro",
41044
+ cost: {
41045
+ input: 1.74,
41046
+ output: 3.48,
41047
+ cacheRead: 0.145,
41048
+ cacheWrite: 1.74
41049
+ }
41050
+ }
41051
+ ];
41052
+ function createDeepseekProviderConfig() {
41053
+ return {
41054
+ baseUrl: DEEPSEEK_BASE_URL,
41055
+ apiKey: "env:DEEPSEEK_API_KEY",
41056
+ api: "openai-completions",
41057
+ models: DEEPSEEK_MODELS.map((model) => ({
41058
+ id: model.id,
41059
+ name: model.name,
41060
+ reasoning: true,
41061
+ input: ["text"],
41062
+ contextWindow: 1e6,
41063
+ maxTokens: 384e3,
41064
+ cost: {
41065
+ input: model.cost.input,
41066
+ output: model.cost.output,
41067
+ cacheRead: model.cost.cacheRead,
41068
+ cacheWrite: model.cost.cacheWrite
41069
+ },
41070
+ compat: {
41071
+ supportsReasoningEffort: true,
41072
+ reasoningEffortMap: {
41073
+ minimal: "high",
41074
+ low: "high",
41075
+ medium: "high",
41076
+ high: "high",
41077
+ xhigh: "max"
41078
+ }
41079
+ }
41080
+ }))
41081
+ };
41082
+ }
41024
41083
  function createAzureProviderConfig(params) {
41025
41084
  const providerConfig = {
41026
41085
  baseUrl: params.baseUrl,
@@ -41112,7 +41171,7 @@ async function resolveKnowledgeProviderFromAgentRuntime(params) {
41112
41171
  }
41113
41172
  };
41114
41173
  }
41115
- const agentRootPath = resolveDocyrusPiAgentRootPath(params.settingsRootPath);
41174
+ const agentRootPath = params.piAgentRootPath ?? getDocyrusPiAgentGlobalRootPath();
41116
41175
  const authState = readJsonFile((0, import_node_path12.join)(agentRootPath, "auth.json")) || {};
41117
41176
  const envStore = new AgentEnvStore((0, import_node_path12.join)(agentRootPath, "env.json"));
41118
41177
  const envState = await envStore.readState();
@@ -42709,6 +42768,20 @@ async function saveCustomOpenAiConfig(params) {
42709
42768
  }));
42710
42769
  params.settingsManager.setDefaultModelAndProvider("custom-openai", params.modelId.trim());
42711
42770
  }
42771
+ async function saveDeepseekConfig(params) {
42772
+ const apiKey = params.apiKey.trim();
42773
+ const modelId = params.modelId?.trim() || DEEPSEEK_MODELS[0].id;
42774
+ params.authStorage.set("deepseek", {
42775
+ type: "api_key",
42776
+ key: apiKey
42777
+ });
42778
+ await params.envStore.removeMany(["DEEPSEEK_API_KEY"]);
42779
+ await params.envStore.setMany({
42780
+ DEEPSEEK_API_KEY: apiKey
42781
+ });
42782
+ await upsertModelsProvider(params.modelsJsonPath, "deepseek", createDeepseekProviderConfig());
42783
+ params.settingsManager.setDefaultModelAndProvider("deepseek", modelId);
42784
+ }
42712
42785
  async function saveAzureConfig(params) {
42713
42786
  const modelId = params.modelId.trim();
42714
42787
  const useCustomModel = params.useCustomModel ?? false;
@@ -42786,6 +42859,12 @@ async function clearProviderConfig(params) {
42786
42859
  ]);
42787
42860
  await removeModelsProvider(params.modelsJsonPath, "custom-openai");
42788
42861
  }
42862
+ if (params.providerId === "deepseek") {
42863
+ await params.envStore.removeMany([
42864
+ "DEEPSEEK_API_KEY"
42865
+ ]);
42866
+ await removeModelsProvider(params.modelsJsonPath, "deepseek");
42867
+ }
42789
42868
  if (params.providerId === "azure-openai-responses") {
42790
42869
  await params.envStore.removeMany([
42791
42870
  "AZURE_OPENAI_API_KEY",
@@ -42830,6 +42909,7 @@ var PROVIDER_LABELS = {
42830
42909
  mistral: "Mistral",
42831
42910
  minimax: "MiniMax",
42832
42911
  "minimax-cn": "MiniMax CN",
42912
+ deepseek: "DeepSeek",
42833
42913
  huggingface: "Hugging Face",
42834
42914
  opencode: "OpenCode",
42835
42915
  "opencode-go": "OpenCode Go",
@@ -42843,6 +42923,7 @@ var PROVIDER_LABELS = {
42843
42923
  var PROVIDER_HINTS = {
42844
42924
  anthropic: "recommended",
42845
42925
  "custom-openai": "custom base URL + API key",
42926
+ deepseek: "API key (OpenAI-compatible preset)",
42846
42927
  "azure-openai-responses": "API key + base URL/resource + deployment",
42847
42928
  "amazon-bedrock": "AWS profile or access key pair",
42848
42929
  "openai-codex": "browser auth",
@@ -42885,6 +42966,8 @@ function getApiKeyProviderOptions(providerIds) {
42885
42966
  flow3 = "azure-openai-responses";
42886
42967
  } else if (providerId === "amazon-bedrock") {
42887
42968
  flow3 = "amazon-bedrock";
42969
+ } else if (providerId === "deepseek") {
42970
+ flow3 = "deepseek";
42888
42971
  }
42889
42972
  return {
42890
42973
  id: providerId,
@@ -42899,6 +42982,12 @@ function getApiKeyProviderOptions(providerIds) {
42899
42982
  hint: toHint("custom-openai"),
42900
42983
  flow: "custom-openai"
42901
42984
  });
42985
+ baseProviders.push({
42986
+ id: "deepseek",
42987
+ label: toLabel("deepseek"),
42988
+ hint: toHint("deepseek"),
42989
+ flow: "deepseek"
42990
+ });
42902
42991
  const deduped = /* @__PURE__ */ new Map();
42903
42992
  for (const provider of baseProviders) {
42904
42993
  deduped.set(provider.id, provider);
@@ -42960,6 +43049,23 @@ function getProviderFormFields(params) {
42960
43049
  placeholder: "gpt-4o"
42961
43050
  }
42962
43051
  ];
43052
+ case "deepseek":
43053
+ return [
43054
+ {
43055
+ name: "apiKey",
43056
+ title: `${provider.label} API key`,
43057
+ required: true,
43058
+ component: "password"
43059
+ },
43060
+ {
43061
+ name: "modelId",
43062
+ title: "Model",
43063
+ required: true,
43064
+ component: "select",
43065
+ options: DEEPSEEK_MODELS.map((model) => ({ label: model.name, value: model.id })),
43066
+ defaultValue: DEEPSEEK_MODELS[0].id
43067
+ }
43068
+ ];
42963
43069
  case "azure-openai-responses":
42964
43070
  return [
42965
43071
  {
@@ -43208,6 +43314,15 @@ async function applyProviderLogin(params) {
43208
43314
  });
43209
43315
  return { providerId: provider.id, preferredModelId: params.input.modelId };
43210
43316
  }
43317
+ case "deepseek": {
43318
+ const modelId = params.input.modelId ?? DEEPSEEK_MODELS[0].id;
43319
+ await saveDeepseekConfig({
43320
+ ...params,
43321
+ apiKey: params.input.apiKey,
43322
+ modelId
43323
+ });
43324
+ return { providerId: provider.id, preferredModelId: modelId };
43325
+ }
43211
43326
  case "azure-openai-responses": {
43212
43327
  const baseUrl = params.input.baseUrl ?? (params.input.resourceName ? `https://${params.input.resourceName}.openai.azure.com/openai` : void 0);
43213
43328
  if (!baseUrl) {
@@ -47732,25 +47847,11 @@ function setProcessArgValue(flag, value2) {
47732
47847
  }
47733
47848
  process.argv.push(flag, value2);
47734
47849
  }
47735
- function buildTools(profile, cwd, pi) {
47850
+ function buildTools(profile) {
47736
47851
  if (profile === "agent") {
47737
- return [
47738
- pi.createReadTool(cwd),
47739
- pi.createBashTool(cwd),
47740
- pi.createGrepTool(cwd),
47741
- pi.createFindTool(cwd),
47742
- pi.createLsTool(cwd)
47743
- ];
47852
+ return ["read", "bash", "grep", "find", "ls"];
47744
47853
  }
47745
- return [
47746
- pi.createReadTool(cwd),
47747
- pi.createBashTool(cwd),
47748
- pi.createEditTool(cwd),
47749
- pi.createWriteTool(cwd),
47750
- pi.createGrepTool(cwd),
47751
- pi.createFindTool(cwd),
47752
- pi.createLsTool(cwd)
47753
- ];
47854
+ return ["read", "bash", "edit", "write", "grep", "find", "ls"];
47754
47855
  }
47755
47856
  function resolveRequestedModel(params) {
47756
47857
  const { request, modelRegistry } = params;
@@ -47862,7 +47963,7 @@ async function main() {
47862
47963
  resourceLoader,
47863
47964
  settingsManager,
47864
47965
  sessionManager,
47865
- tools: buildTools(request.profile, cwd, pi),
47966
+ tools: buildTools(request.profile),
47866
47967
  model: requestedModel,
47867
47968
  thinkingLevel: request.thinking
47868
47969
  });
@@ -47922,7 +48023,7 @@ async function main() {
47922
48023
  resourceLoader,
47923
48024
  settingsManager,
47924
48025
  sessionManager,
47925
- tools: buildTools(request.profile, cwd, pi),
48026
+ tools: buildTools(request.profile),
47926
48027
  model: requestedModel,
47927
48028
  thinkingLevel: request.thinking
47928
48029
  });
@@ -47957,7 +48058,7 @@ async function main() {
47957
48058
  resourceLoader,
47958
48059
  settingsManager,
47959
48060
  sessionManager: resumedSessionManager,
47960
- tools: buildTools(request.profile, resumeCwd, pi),
48061
+ tools: buildTools(request.profile),
47961
48062
  model: requestedModel,
47962
48063
  thinkingLevel: request.thinking
47963
48064
  });