@bike4mind/cli 0.2.4-feat-questmaster-external-integrations.17096 → 0.2.5-feat-cli-dynamic-model-fetching.17089

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/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-UHTQGQB4.js";
8
- import "./chunk-7OJVF5WR.js";
9
- import "./chunk-3BPXGCV5.js";
7
+ } from "./chunk-WNBKV4FX.js";
8
+ import "./chunk-LEG2UM5Q.js";
9
+ import "./chunk-6AJODFPC.js";
10
10
  import {
11
11
  BFLImageService,
12
12
  BaseStorage,
@@ -15,7 +15,7 @@ import {
15
15
  OpenAIBackend,
16
16
  OpenAIImageService,
17
17
  XAIImageService
18
- } from "./chunk-2IW5ZJXR.js";
18
+ } from "./chunk-LYNNVNEC.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-AMDXHL6S.js";
@@ -73,7 +73,7 @@ import {
73
73
  XAI_IMAGE_MODELS,
74
74
  b4mLLMTools,
75
75
  getMcpProviderMetadata
76
- } from "./chunk-PVLFZFW3.js";
76
+ } from "./chunk-WR6YZRQV.js";
77
77
  import {
78
78
  __require
79
79
  } from "./chunk-PDX44BCA.js";
@@ -90,10 +90,8 @@ import { Box as Box9, Text as Text8, Static } from "ink";
90
90
  // src/components/StatusBar.tsx
91
91
  import React from "react";
92
92
  import { Box, Text } from "ink";
93
- var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage, quest }) {
94
- const questDisplay = quest ? `${quest.questTitle || quest.questPlanName} (${quest.progress.completed}/${quest.progress.total})` : null;
95
- const syncIndicator = quest?.syncStatus === "offline" ? " \u26A0\uFE0F" : quest?.syncStatus === "pending" ? " \u23F3" : "";
96
- return /* @__PURE__ */ React.createElement(Box, { borderStyle: "single", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "green", bold: true }, "\u{1F4DD} Session:"), /* @__PURE__ */ React.createElement(Text, null, sessionName)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "blue", bold: true }, "\u{1F916} Model:"), /* @__PURE__ */ React.createElement(Text, null, model)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow", bold: true }, "\u{1F4CA} Tokens:"), /* @__PURE__ */ React.createElement(Text, null, tokenUsage.toLocaleString())), questDisplay && /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "magenta", bold: true }, "\u{1F3AF} Quest:"), /* @__PURE__ */ React.createElement(Text, null, questDisplay, syncIndicator))));
93
+ var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage }) {
94
+ return /* @__PURE__ */ React.createElement(Box, { borderStyle: "single", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "green", bold: true }, "\u{1F4DD} Session:"), /* @__PURE__ */ React.createElement(Text, null, sessionName)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "blue", bold: true }, "\u{1F916} Model:"), /* @__PURE__ */ React.createElement(Text, null, model)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow", bold: true }, "\u{1F4CA} Tokens:"), /* @__PURE__ */ React.createElement(Text, null, tokenUsage.toLocaleString()))));
97
95
  });
98
96
 
99
97
  // src/components/InputPrompt.tsx
@@ -391,25 +389,6 @@ var COMMANDS = [
391
389
  name: "clear",
392
390
  description: "Start a new session",
393
391
  aliases: ["new"]
394
- },
395
- {
396
- name: "quest",
397
- description: "Load a quest into current session",
398
- args: "<quest-id>",
399
- aliases: ["q"]
400
- },
401
- {
402
- name: "quest-status",
403
- description: "Show current quest progress",
404
- aliases: ["qs"]
405
- },
406
- {
407
- name: "quest-unlink",
408
- description: "Unlink quest from current session"
409
- },
410
- {
411
- name: "plan",
412
- description: "Create a QuestMaster plan from current context"
413
392
  }
414
393
  ];
415
394
 
@@ -706,100 +685,119 @@ var EXPORT_FORMAT_OPTIONS = [
706
685
  { label: "markdown", value: "markdown" },
707
686
  { label: "json", value: "json" }
708
687
  ];
709
- var CONFIG_ITEMS = [
710
- {
711
- key: "maxIterations",
712
- label: "Max Iterations",
713
- type: "select",
714
- options: MAX_ITERATIONS_OPTIONS,
715
- getValue: (config) => config.preferences.maxIterations,
716
- setValue: (config, value) => ({
717
- ...config,
718
- preferences: {
719
- ...config.preferences,
720
- maxIterations: value
721
- }
722
- })
723
- },
724
- {
725
- key: "maxTokens",
726
- label: "Max Tokens",
727
- type: "number",
728
- min: 256,
729
- max: 128e3,
730
- step: 256,
731
- getValue: (config) => config.preferences.maxTokens,
732
- setValue: (config, value) => ({
733
- ...config,
734
- preferences: {
735
- ...config.preferences,
736
- maxTokens: value
737
- }
738
- })
739
- },
740
- {
741
- key: "temperature",
742
- label: "Temperature",
743
- type: "number",
744
- min: 0,
745
- max: 2,
746
- step: 0.1,
747
- getValue: (config) => config.preferences.temperature,
748
- setValue: (config, value) => ({
749
- ...config,
750
- preferences: {
751
- ...config.preferences,
752
- temperature: value
753
- }
754
- })
755
- },
756
- {
757
- key: "autoSave",
758
- label: "Auto Save",
759
- type: "boolean",
760
- getValue: (config) => config.preferences.autoSave,
761
- setValue: (config, value) => ({
762
- ...config,
763
- preferences: {
764
- ...config.preferences,
765
- autoSave: value
766
- }
767
- })
768
- },
769
- {
770
- key: "theme",
771
- label: "Theme",
772
- type: "select",
773
- options: THEME_OPTIONS,
774
- getValue: (config) => config.preferences.theme,
775
- setValue: (config, value) => ({
776
- ...config,
777
- preferences: {
778
- ...config.preferences,
779
- theme: value
780
- }
781
- })
782
- },
783
- {
784
- key: "exportFormat",
785
- label: "Export Format",
786
- type: "select",
787
- options: EXPORT_FORMAT_OPTIONS,
788
- getValue: (config) => config.preferences.exportFormat,
789
- setValue: (config, value) => ({
790
- ...config,
791
- preferences: {
792
- ...config.preferences,
793
- exportFormat: value
794
- }
795
- })
796
- }
797
- ];
798
- function ConfigEditor({ config, onSave, onClose }) {
688
+ function buildConfigItems(availableModels) {
689
+ const modelOptions = availableModels.map((model) => ({
690
+ label: model.name,
691
+ value: model.id
692
+ }));
693
+ return [
694
+ // Model selection - first item (most important)
695
+ {
696
+ key: "model",
697
+ label: "Model",
698
+ type: "select",
699
+ options: modelOptions,
700
+ getValue: (config) => config.defaultModel,
701
+ setValue: (config, value) => ({
702
+ ...config,
703
+ defaultModel: value
704
+ })
705
+ },
706
+ {
707
+ key: "maxIterations",
708
+ label: "Max Iterations",
709
+ type: "select",
710
+ options: MAX_ITERATIONS_OPTIONS,
711
+ getValue: (config) => config.preferences.maxIterations,
712
+ setValue: (config, value) => ({
713
+ ...config,
714
+ preferences: {
715
+ ...config.preferences,
716
+ maxIterations: value
717
+ }
718
+ })
719
+ },
720
+ {
721
+ key: "maxTokens",
722
+ label: "Max Tokens",
723
+ type: "number",
724
+ min: 256,
725
+ max: 128e3,
726
+ step: 256,
727
+ getValue: (config) => config.preferences.maxTokens,
728
+ setValue: (config, value) => ({
729
+ ...config,
730
+ preferences: {
731
+ ...config.preferences,
732
+ maxTokens: value
733
+ }
734
+ })
735
+ },
736
+ {
737
+ key: "temperature",
738
+ label: "Temperature",
739
+ type: "number",
740
+ min: 0,
741
+ max: 2,
742
+ step: 0.1,
743
+ getValue: (config) => config.preferences.temperature,
744
+ setValue: (config, value) => ({
745
+ ...config,
746
+ preferences: {
747
+ ...config.preferences,
748
+ temperature: value
749
+ }
750
+ })
751
+ },
752
+ {
753
+ key: "autoSave",
754
+ label: "Auto Save",
755
+ type: "boolean",
756
+ getValue: (config) => config.preferences.autoSave,
757
+ setValue: (config, value) => ({
758
+ ...config,
759
+ preferences: {
760
+ ...config.preferences,
761
+ autoSave: value
762
+ }
763
+ })
764
+ },
765
+ {
766
+ key: "theme",
767
+ label: "Theme",
768
+ type: "select",
769
+ options: THEME_OPTIONS,
770
+ getValue: (config) => config.preferences.theme,
771
+ setValue: (config, value) => ({
772
+ ...config,
773
+ preferences: {
774
+ ...config.preferences,
775
+ theme: value
776
+ }
777
+ })
778
+ },
779
+ {
780
+ key: "exportFormat",
781
+ label: "Export Format",
782
+ type: "select",
783
+ options: EXPORT_FORMAT_OPTIONS,
784
+ getValue: (config) => config.preferences.exportFormat,
785
+ setValue: (config, value) => ({
786
+ ...config,
787
+ preferences: {
788
+ ...config.preferences,
789
+ exportFormat: value
790
+ }
791
+ })
792
+ }
793
+ ];
794
+ }
795
+ function ConfigEditor({ config, availableModels, onSave, onClose }) {
799
796
  const [selectedIndex, setSelectedIndex] = useState2(0);
800
797
  const [editedConfig, setEditedConfig] = useState2(config);
801
798
  const [saveError, setSaveError] = useState2(null);
802
799
  const [isSaving, setIsSaving] = useState2(false);
800
+ const configItems = useMemo2(() => buildConfigItems(availableModels), [availableModels]);
803
801
  const hasChanges = useMemo2(() => {
804
802
  return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences);
805
803
  }, [config.preferences, editedConfig.preferences]);
@@ -819,13 +817,13 @@ function ConfigEditor({ config, onSave, onClose }) {
819
817
  onClose();
820
818
  };
821
819
  useInput2((input, key) => {
822
- const currentItem = CONFIG_ITEMS[selectedIndex];
820
+ const currentItem = configItems[selectedIndex];
823
821
  if (key.upArrow) {
824
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : CONFIG_ITEMS.length - 1);
822
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : configItems.length - 1);
825
823
  return;
826
824
  }
827
825
  if (key.downArrow) {
828
- setSelectedIndex((prev) => prev < CONFIG_ITEMS.length - 1 ? prev + 1 : 0);
826
+ setSelectedIndex((prev) => prev < configItems.length - 1 ? prev + 1 : 0);
829
827
  return;
830
828
  }
831
829
  if ((key.escape || input === "q") && !isSaving) {
@@ -883,7 +881,7 @@ function ConfigEditor({ config, onSave, onClose }) {
883
881
  }
884
882
  return String(value);
885
883
  };
886
- return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React8.createElement(Text7, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React8.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, CONFIG_ITEMS.map((item, index) => {
884
+ return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React8.createElement(Text7, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React8.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, configItems.map((item, index) => {
887
885
  const isSelected = index === selectedIndex;
888
886
  const value = item.getValue(editedConfig);
889
887
  const displayValue = formatValue(item, value);
@@ -1013,13 +1011,13 @@ function App({
1013
1011
  onPermissionResponse,
1014
1012
  commandHistory = [],
1015
1013
  config,
1014
+ availableModels = [],
1016
1015
  onSaveConfig
1017
1016
  }) {
1018
1017
  const messages = useCliStore((state) => state.session?.messages || []);
1019
1018
  const sessionName = useCliStore((state) => state.session?.name || "New Session");
1020
1019
  const currentModel = useCliStore((state) => state.session?.model || "claude-sonnet-4-5-20250929");
1021
1020
  const totalTokens = useCliStore((state) => state.session?.metadata.totalTokens || 0);
1022
- const quest = useCliStore((state) => state.session?.quest);
1023
1021
  const isThinking = useCliStore((state) => state.isThinking);
1024
1022
  const permissionPrompt = useCliStore((state) => state.permissionPrompt);
1025
1023
  const showConfigEditor = useCliStore((state) => state.showConfigEditor);
@@ -1055,7 +1053,15 @@ ${errorBlock}`;
1055
1053
  },
1056
1054
  [onMessage, onCommand, setIsThinking]
1057
1055
  );
1058
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens, quest }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(ConfigEditor, { config, onSave: onSaveConfig, onClose: () => setShowConfigEditor(false) })) : permissionPrompt ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
1056
+ return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
1057
+ ConfigEditor,
1058
+ {
1059
+ config,
1060
+ availableModels,
1061
+ onSave: onSaveConfig,
1062
+ onClose: () => setShowConfigEditor(false)
1063
+ }
1064
+ )) : permissionPrompt ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
1059
1065
  PermissionPrompt,
1060
1066
  {
1061
1067
  toolName: permissionPrompt.toolName,
@@ -4116,16 +4122,6 @@ var updateQuestStatusSchema = z134.object({
4116
4122
  completionNote: z134.string().max(500).optional()
4117
4123
  });
4118
4124
 
4119
- // ../../b4m-core/packages/services/dist/src/questMasterService/syncToGitHub.js
4120
- import { z as z135 } from "zod";
4121
- var syncToGitHubSchema = z135.object({
4122
- repository: z135.string().regex(/^[^/]+\/[^/]+$/, "Repository must be in owner/repo format"),
4123
- questId: z135.string().optional(),
4124
- // Optional: sync specific quest, otherwise sync entire plan
4125
- labels: z135.array(z135.string()).optional(),
4126
- assignees: z135.array(z135.string()).optional()
4127
- });
4128
-
4129
4125
  // ../../b4m-core/packages/services/dist/src/dataLakeService/opensearchClient.js
4130
4126
  import { Client } from "@opensearch-project/opensearch";
4131
4127
  import { defaultProvider } from "@aws-sdk/credential-provider-node";
@@ -4143,63 +4139,63 @@ import { v4 as uuidv44 } from "uuid";
4143
4139
  import { randomUUID as randomUUID5 } from "crypto";
4144
4140
 
4145
4141
  // ../../b4m-core/packages/services/dist/src/emailIngestionService/types.js
4146
- import { z as z136 } from "zod";
4147
- var processIngestedEmailOptionsSchema = z136.object({
4148
- platformDomain: z136.string().optional(),
4149
- isNewsletter: z136.boolean().optional()
4142
+ import { z as z135 } from "zod";
4143
+ var processIngestedEmailOptionsSchema = z135.object({
4144
+ platformDomain: z135.string().optional(),
4145
+ isNewsletter: z135.boolean().optional()
4150
4146
  }).optional();
4151
- var emailAttachmentSchema = z136.object({
4152
- filename: z136.string().optional(),
4153
- contentType: z136.string().optional(),
4154
- contentDisposition: z136.string().optional(),
4155
- size: z136.number().min(0),
4156
- content: z136.instanceof(Buffer),
4157
- related: z136.boolean().optional()
4158
- });
4159
- var parsedEmailObjectSchema = z136.object({
4160
- messageId: z136.string().optional(),
4161
- inReplyTo: z136.string().optional(),
4162
- references: z136.union([z136.string(), z136.array(z136.string())]).optional(),
4163
- from: z136.any().optional(),
4147
+ var emailAttachmentSchema = z135.object({
4148
+ filename: z135.string().optional(),
4149
+ contentType: z135.string().optional(),
4150
+ contentDisposition: z135.string().optional(),
4151
+ size: z135.number().min(0),
4152
+ content: z135.instanceof(Buffer),
4153
+ related: z135.boolean().optional()
4154
+ });
4155
+ var parsedEmailObjectSchema = z135.object({
4156
+ messageId: z135.string().optional(),
4157
+ inReplyTo: z135.string().optional(),
4158
+ references: z135.union([z135.string(), z135.array(z135.string())]).optional(),
4159
+ from: z135.any().optional(),
4164
4160
  // Complex email address object
4165
- to: z136.any().optional(),
4166
- cc: z136.any().optional(),
4167
- bcc: z136.any().optional(),
4168
- subject: z136.string().optional(),
4169
- date: z136.date().optional(),
4170
- text: z136.string().optional(),
4171
- html: z136.string().optional(),
4172
- attachments: z136.array(emailAttachmentSchema).optional()
4173
- });
4174
- var processIngestedEmailSchema = z136.object({
4161
+ to: z135.any().optional(),
4162
+ cc: z135.any().optional(),
4163
+ bcc: z135.any().optional(),
4164
+ subject: z135.string().optional(),
4165
+ date: z135.date().optional(),
4166
+ text: z135.string().optional(),
4167
+ html: z135.string().optional(),
4168
+ attachments: z135.array(emailAttachmentSchema).optional()
4169
+ });
4170
+ var processIngestedEmailSchema = z135.object({
4175
4171
  parsedEmail: parsedEmailObjectSchema,
4176
- rawEmailS3Key: z136.string().min(1, "rawEmailS3Key cannot be empty"),
4172
+ rawEmailS3Key: z135.string().min(1, "rawEmailS3Key cannot be empty"),
4177
4173
  options: processIngestedEmailOptionsSchema
4178
4174
  });
4179
4175
 
4180
4176
  // ../../b4m-core/packages/services/dist/src/emailAnalysisService/types.js
4181
- import { z as z137 } from "zod";
4182
- var llmAnalysisResponseSchema = z137.object({
4183
- summary: z137.string().min(1, "Summary cannot be empty"),
4184
- entities: z137.object({
4185
- companies: z137.array(z137.string()).default([]),
4186
- people: z137.array(z137.string()).default([]),
4187
- products: z137.array(z137.string()).default([]),
4188
- technologies: z137.array(z137.string()).default([])
4177
+ import { z as z136 } from "zod";
4178
+ var llmAnalysisResponseSchema = z136.object({
4179
+ summary: z136.string().min(1, "Summary cannot be empty"),
4180
+ entities: z136.object({
4181
+ companies: z136.array(z136.string()).default([]),
4182
+ people: z136.array(z136.string()).default([]),
4183
+ products: z136.array(z136.string()).default([]),
4184
+ technologies: z136.array(z136.string()).default([])
4189
4185
  }),
4190
- sentiment: z137.enum(["positive", "neutral", "negative", "urgent"]),
4191
- actionItems: z137.array(z137.object({
4192
- description: z137.string(),
4193
- deadline: z137.string().optional()
4186
+ sentiment: z136.enum(["positive", "neutral", "negative", "urgent"]),
4187
+ actionItems: z136.array(z136.object({
4188
+ description: z136.string(),
4189
+ deadline: z136.string().optional()
4194
4190
  // ISO date string from LLM
4195
4191
  })).default([]),
4196
- privacyRecommendation: z137.enum(["public", "team", "private"]),
4197
- embargoDetected: z137.boolean().default(false),
4198
- suggestedTags: z137.array(z137.string()).default([])
4192
+ privacyRecommendation: z136.enum(["public", "team", "private"]),
4193
+ embargoDetected: z136.boolean().default(false),
4194
+ suggestedTags: z136.array(z136.string()).default([])
4199
4195
  });
4200
4196
 
4201
4197
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
4202
- import { z as z139 } from "zod";
4198
+ import { z as z138 } from "zod";
4203
4199
 
4204
4200
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
4205
4201
  import { fromZodError } from "zod-validation-error";
@@ -5259,17 +5255,17 @@ var rechartsTool = {
5259
5255
  };
5260
5256
 
5261
5257
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editFile/index.js
5262
- import { z as z138 } from "zod";
5258
+ import { z as z137 } from "zod";
5263
5259
  import { diffLines as diffLines2 } from "diff";
5264
- var editFileSchema = z138.object({
5265
- fileId: z138.string().describe("The ID of the file to edit"),
5266
- instruction: z138.string().describe("Natural language instruction describing the changes to make"),
5267
- selection: z138.object({
5268
- start: z138.number().describe("Starting character position of the selection"),
5269
- end: z138.number().describe("Ending character position of the selection")
5260
+ var editFileSchema = z137.object({
5261
+ fileId: z137.string().describe("The ID of the file to edit"),
5262
+ instruction: z137.string().describe("Natural language instruction describing the changes to make"),
5263
+ selection: z137.object({
5264
+ start: z137.number().describe("Starting character position of the selection"),
5265
+ end: z137.number().describe("Ending character position of the selection")
5270
5266
  }).optional().describe("Optional selection range to edit within the file"),
5271
- preserveFormatting: z138.boolean().optional().default(true).describe("Whether to preserve the original formatting style"),
5272
- returnDiff: z138.boolean().optional().default(true).describe("Whether to return a diff of the changes")
5267
+ preserveFormatting: z137.boolean().optional().default(true).describe("Whether to preserve the original formatting style"),
5268
+ returnDiff: z137.boolean().optional().default(true).describe("Whether to return a diff of the changes")
5273
5269
  });
5274
5270
  function generateSimpleDiff(original, modified) {
5275
5271
  const differences = diffLines2(original, modified);
@@ -7028,8 +7024,8 @@ var getHeliocentricCoords = (planet, T) => {
7028
7024
  const sinNode = Math.sin(longNode);
7029
7025
  const x = r * (cosNode * cosOmega - sinNode * sinOmega * cosI);
7030
7026
  const y = r * (sinNode * cosOmega + cosNode * sinOmega * cosI);
7031
- const z145 = r * sinOmega * sinI;
7032
- return { x, y, z: z145, r };
7027
+ const z144 = r * sinOmega * sinI;
7028
+ return { x, y, z: z144, r };
7033
7029
  };
7034
7030
  var getGeocentricEcliptic = (planet, earth) => {
7035
7031
  const dx = planet.x - earth.x;
@@ -8054,42 +8050,42 @@ var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true"
8054
8050
  var questSaveMutex = new Mutex();
8055
8051
 
8056
8052
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
8057
- var QuestStartBodySchema = z139.object({
8058
- userId: z139.string(),
8059
- sessionId: z139.string(),
8060
- questId: z139.string(),
8061
- message: z139.string(),
8062
- messageFileIds: z139.array(z139.string()),
8063
- historyCount: z139.number(),
8064
- fabFileIds: z139.array(z139.string()),
8053
+ var QuestStartBodySchema = z138.object({
8054
+ userId: z138.string(),
8055
+ sessionId: z138.string(),
8056
+ questId: z138.string(),
8057
+ message: z138.string(),
8058
+ messageFileIds: z138.array(z138.string()),
8059
+ historyCount: z138.number(),
8060
+ fabFileIds: z138.array(z138.string()),
8065
8061
  params: ChatCompletionCreateInputSchema,
8066
8062
  dashboardParams: DashboardParamsSchema.optional(),
8067
- enableQuestMaster: z139.boolean().optional(),
8068
- enableMementos: z139.boolean().optional(),
8069
- enableArtifacts: z139.boolean().optional(),
8070
- enableAgents: z139.boolean().optional(),
8063
+ enableQuestMaster: z138.boolean().optional(),
8064
+ enableMementos: z138.boolean().optional(),
8065
+ enableArtifacts: z138.boolean().optional(),
8066
+ enableAgents: z138.boolean().optional(),
8071
8067
  promptMeta: PromptMetaZodSchema,
8072
- tools: z139.array(z139.union([b4mLLMTools, z139.string()])).optional(),
8073
- mcpServers: z139.array(z139.string()).optional(),
8074
- projectId: z139.string().optional(),
8075
- organizationId: z139.string().nullable().optional(),
8068
+ tools: z138.array(z138.union([b4mLLMTools, z138.string()])).optional(),
8069
+ mcpServers: z138.array(z138.string()).optional(),
8070
+ projectId: z138.string().optional(),
8071
+ organizationId: z138.string().nullable().optional(),
8076
8072
  questMaster: QuestMasterParamsSchema.optional(),
8077
- toolPromptId: z139.string().optional(),
8073
+ toolPromptId: z138.string().optional(),
8078
8074
  researchMode: ResearchModeParamsSchema.optional(),
8079
- fallbackModel: z139.string().optional(),
8080
- embeddingModel: z139.string().optional(),
8081
- queryComplexity: z139.string(),
8075
+ fallbackModel: z138.string().optional(),
8076
+ embeddingModel: z138.string().optional(),
8077
+ queryComplexity: z138.string(),
8082
8078
  imageConfig: GenerateImageToolCallSchema.optional(),
8083
- deepResearchConfig: z139.object({
8084
- maxDepth: z139.number().optional(),
8085
- duration: z139.number().optional(),
8079
+ deepResearchConfig: z138.object({
8080
+ maxDepth: z138.number().optional(),
8081
+ duration: z138.number().optional(),
8086
8082
  // Note: searchers are passed via ToolContext and not through this API schema
8087
- searchers: z139.array(z139.any()).optional()
8083
+ searchers: z138.array(z138.any()).optional()
8088
8084
  }).optional(),
8089
- extraContextMessages: z139.array(z139.object({
8090
- role: z139.enum(["user", "assistant", "system", "function", "tool"]),
8091
- content: z139.union([z139.string(), z139.array(z139.any())]),
8092
- fabFileIds: z139.array(z139.string()).optional()
8085
+ extraContextMessages: z138.array(z138.object({
8086
+ role: z138.enum(["user", "assistant", "system", "function", "tool"]),
8087
+ content: z138.union([z138.string(), z138.array(z138.any())]),
8088
+ fabFileIds: z138.array(z138.string()).optional()
8093
8089
  })).optional()
8094
8090
  });
8095
8091
 
@@ -8097,9 +8093,30 @@ var QuestStartBodySchema = z139.object({
8097
8093
  import axios8 from "axios";
8098
8094
  import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
8099
8095
  import { v4 as uuidv47 } from "uuid";
8100
- import { z as z140 } from "zod";
8096
+ import { z as z139 } from "zod";
8101
8097
  import { fromZodError as fromZodError2 } from "zod-validation-error";
8102
8098
  var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
8099
+ sessionId: z139.string(),
8100
+ questId: z139.string(),
8101
+ userId: z139.string(),
8102
+ prompt: z139.string(),
8103
+ safety_tolerance: z139.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
8104
+ prompt_upsampling: z139.boolean().optional().default(false),
8105
+ seed: z139.number().nullable().optional(),
8106
+ output_format: z139.enum(["jpeg", "png"]).nullable().optional().default("png"),
8107
+ width: z139.number().optional(),
8108
+ height: z139.number().optional(),
8109
+ aspect_ratio: z139.string().optional(),
8110
+ fabFileIds: z139.array(z139.string()).optional()
8111
+ });
8112
+
8113
+ // ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
8114
+ import axios9 from "axios";
8115
+ import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
8116
+ import { v4 as uuidv48 } from "uuid";
8117
+ import { z as z140 } from "zod";
8118
+ import { fromZodError as fromZodError3 } from "zod-validation-error";
8119
+ var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
8103
8120
  sessionId: z140.string(),
8104
8121
  questId: z140.string(),
8105
8122
  userId: z140.string(),
@@ -8107,56 +8124,35 @@ var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
8107
8124
  safety_tolerance: z140.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
8108
8125
  prompt_upsampling: z140.boolean().optional().default(false),
8109
8126
  seed: z140.number().nullable().optional(),
8110
- output_format: z140.enum(["jpeg", "png"]).nullable().optional().default("png"),
8127
+ output_format: z140.enum(["jpeg", "png"]).optional().default("png"),
8111
8128
  width: z140.number().optional(),
8112
8129
  height: z140.number().optional(),
8113
8130
  aspect_ratio: z140.string().optional(),
8114
- fabFileIds: z140.array(z140.string()).optional()
8115
- });
8116
-
8117
- // ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
8118
- import axios9 from "axios";
8119
- import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
8120
- import { v4 as uuidv48 } from "uuid";
8121
- import { z as z141 } from "zod";
8122
- import { fromZodError as fromZodError3 } from "zod-validation-error";
8123
- var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
8124
- sessionId: z141.string(),
8125
- questId: z141.string(),
8126
- userId: z141.string(),
8127
- prompt: z141.string(),
8128
- safety_tolerance: z141.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
8129
- prompt_upsampling: z141.boolean().optional().default(false),
8130
- seed: z141.number().nullable().optional(),
8131
- output_format: z141.enum(["jpeg", "png"]).optional().default("png"),
8132
- width: z141.number().optional(),
8133
- height: z141.number().optional(),
8134
- aspect_ratio: z141.string().optional(),
8135
- size: z141.string().optional(),
8136
- fabFileIds: z141.array(z141.string()).optional(),
8137
- image: z141.string()
8131
+ size: z140.string().optional(),
8132
+ fabFileIds: z140.array(z140.string()).optional(),
8133
+ image: z140.string()
8138
8134
  });
8139
8135
 
8140
8136
  // ../../b4m-core/packages/services/dist/src/llm/refineText.js
8141
- import { z as z142 } from "zod";
8142
- var refineTextLLMSchema = z142.object({
8143
- text: z142.string(),
8144
- context: z142.string().optional()
8137
+ import { z as z141 } from "zod";
8138
+ var refineTextLLMSchema = z141.object({
8139
+ text: z141.string(),
8140
+ context: z141.string().optional()
8145
8141
  // tone: z.enum(['formal', 'informal', 'neutral']).optional(),
8146
8142
  // style: z.enum(['technical', 'creative', 'academic', 'business', 'narrative']).optional(),
8147
8143
  });
8148
8144
 
8149
8145
  // ../../b4m-core/packages/services/dist/src/llm/MementoEvaluationService.js
8150
- import { z as z143 } from "zod";
8151
- var SingleMementoEvalSchema = z143.object({
8152
- importance: z143.number().min(1).max(10),
8146
+ import { z as z142 } from "zod";
8147
+ var SingleMementoEvalSchema = z142.object({
8148
+ importance: z142.number().min(1).max(10),
8153
8149
  // 1-10 scale for personal info importance
8154
- summary: z143.string(),
8155
- tags: z143.array(z143.string()).optional()
8150
+ summary: z142.string(),
8151
+ tags: z142.array(z142.string()).optional()
8156
8152
  });
8157
- var MementoEvalResponseSchema = z143.object({
8158
- isPersonal: z143.boolean(),
8159
- mementos: z143.array(SingleMementoEvalSchema).optional()
8153
+ var MementoEvalResponseSchema = z142.object({
8154
+ isPersonal: z142.boolean(),
8155
+ mementos: z142.array(SingleMementoEvalSchema).optional()
8160
8156
  // Array of distinct personal information
8161
8157
  });
8162
8158
 
@@ -8393,8 +8389,8 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
8393
8389
  }
8394
8390
 
8395
8391
  // src/config/toolSafety.ts
8396
- import { z as z144 } from "zod";
8397
- var ToolCategorySchema = z144.enum([
8392
+ import { z as z143 } from "zod";
8393
+ var ToolCategorySchema = z143.enum([
8398
8394
  "auto_approve",
8399
8395
  // Safe tools that run automatically without permission
8400
8396
  "prompt_always",
@@ -8402,9 +8398,9 @@ var ToolCategorySchema = z144.enum([
8402
8398
  "prompt_default"
8403
8399
  // Tools that prompt by default but can be trusted
8404
8400
  ]);
8405
- var ToolSafetyConfigSchema = z144.object({
8406
- categories: z144.record(z144.string(), ToolCategorySchema),
8407
- trustedTools: z144.array(z144.string())
8401
+ var ToolSafetyConfigSchema = z143.object({
8402
+ categories: z143.record(z143.string(), ToolCategorySchema),
8403
+ trustedTools: z143.array(z143.string())
8408
8404
  });
8409
8405
  var DEFAULT_TOOL_CATEGORIES = {
8410
8406
  // ===== AUTO APPROVE (Safe tools) =====
@@ -9048,197 +9044,6 @@ var McpManager = class {
9048
9044
  }
9049
9045
  };
9050
9046
 
9051
- // src/utils/QuestTracker.ts
9052
- var QuestTracker = class {
9053
- constructor(apiClient) {
9054
- this.apiClient = apiClient;
9055
- this.pendingUpdates = [];
9056
- this.cachedQuests = /* @__PURE__ */ new Map();
9057
- }
9058
- /**
9059
- * Fetch a quest plan from the API
9060
- */
9061
- async fetchQuestPlan(questPlanId) {
9062
- try {
9063
- const response = await this.apiClient.get(
9064
- `/api/quest-plans/${questPlanId}`
9065
- );
9066
- if (response.success && response.questPlan) {
9067
- this.cachedQuests.set(questPlanId, response.questPlan);
9068
- return response.questPlan;
9069
- }
9070
- return null;
9071
- } catch (error) {
9072
- const cached = this.cachedQuests.get(questPlanId);
9073
- if (cached) {
9074
- console.log("\u26A0\uFE0F Using cached quest data (offline mode)");
9075
- return cached;
9076
- }
9077
- throw error;
9078
- }
9079
- }
9080
- /**
9081
- * Create a SessionQuestLink from quest plan data
9082
- */
9083
- createQuestLink(questPlan, questId) {
9084
- const quest = questId ? questPlan.quests.find((q) => q.id === questId) : null;
9085
- let total = 0;
9086
- let completed = 0;
9087
- if (quest) {
9088
- total = quest.subQuests.length || 1;
9089
- completed = quest.subQuests.filter((sq) => sq.status === "completed").length;
9090
- if (quest.subQuests.length === 0 && quest.status === "completed") {
9091
- completed = 1;
9092
- }
9093
- } else {
9094
- total = questPlan.quests.length;
9095
- completed = questPlan.quests.filter((q) => q.status === "completed").length;
9096
- }
9097
- return {
9098
- questPlanId: questPlan.id,
9099
- questPlanName: questPlan.goal.length > 40 ? questPlan.goal.substring(0, 37) + "..." : questPlan.goal,
9100
- questId,
9101
- questTitle: quest?.title,
9102
- linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
9103
- progress: { total, completed },
9104
- syncStatus: "synced",
9105
- lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString()
9106
- };
9107
- }
9108
- /**
9109
- * Update quest status (queues for sync if offline)
9110
- */
9111
- async updateQuestStatus(questPlanId, status, questId, subQuestId) {
9112
- const update3 = {
9113
- questPlanId,
9114
- questId,
9115
- subQuestId,
9116
- newStatus: status,
9117
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
9118
- };
9119
- try {
9120
- await this.syncUpdate(update3);
9121
- return true;
9122
- } catch (error) {
9123
- this.pendingUpdates.push(update3);
9124
- console.log("\u26A0\uFE0F Update queued for sync when online");
9125
- return false;
9126
- }
9127
- }
9128
- /**
9129
- * Sync a single update to the server
9130
- */
9131
- async syncUpdate(update3) {
9132
- const endpoint = update3.subQuestId ? `/api/quest-plans/${update3.questPlanId}/quests/${update3.questId}/sub-quests/${update3.subQuestId}/status` : update3.questId ? `/api/quest-plans/${update3.questPlanId}/quests/${update3.questId}/status` : `/api/quest-plans/${update3.questPlanId}/status`;
9133
- await this.apiClient.put(endpoint, { status: update3.newStatus });
9134
- }
9135
- /**
9136
- * Sync all pending updates
9137
- */
9138
- async syncPendingUpdates() {
9139
- let synced = 0;
9140
- let failed = 0;
9141
- const remaining = [];
9142
- for (const update3 of this.pendingUpdates) {
9143
- try {
9144
- await this.syncUpdate(update3);
9145
- synced++;
9146
- } catch {
9147
- remaining.push(update3);
9148
- failed++;
9149
- }
9150
- }
9151
- this.pendingUpdates = remaining;
9152
- return { synced, failed };
9153
- }
9154
- /**
9155
- * Get pending update count
9156
- */
9157
- getPendingCount() {
9158
- return this.pendingUpdates.length;
9159
- }
9160
- /**
9161
- * Check if there are pending updates
9162
- */
9163
- hasPendingUpdates() {
9164
- return this.pendingUpdates.length > 0;
9165
- }
9166
- /**
9167
- * Update progress in a SessionQuestLink
9168
- */
9169
- updateProgress(link, questPlan) {
9170
- const quest = link.questId ? questPlan.quests.find((q) => q.id === link.questId) : null;
9171
- let total = 0;
9172
- let completed = 0;
9173
- if (quest) {
9174
- total = quest.subQuests.length || 1;
9175
- completed = quest.subQuests.filter((sq) => sq.status === "completed").length;
9176
- if (quest.subQuests.length === 0 && quest.status === "completed") {
9177
- completed = 1;
9178
- }
9179
- } else {
9180
- total = questPlan.quests.length;
9181
- completed = questPlan.quests.filter((q) => q.status === "completed").length;
9182
- }
9183
- return {
9184
- ...link,
9185
- progress: { total, completed },
9186
- syncStatus: this.hasPendingUpdates() ? "pending" : "synced",
9187
- lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString()
9188
- };
9189
- }
9190
- /**
9191
- * Format quest plan for display
9192
- */
9193
- formatQuestPlan(questPlan) {
9194
- const lines = [];
9195
- lines.push(`
9196
- \u{1F3AF} Quest Plan: ${questPlan.goal}`);
9197
- lines.push(` Status: ${this.formatStatus(questPlan.status)}`);
9198
- lines.push("");
9199
- questPlan.quests.forEach((quest, i) => {
9200
- const statusIcon = this.getStatusIcon(quest.status);
9201
- lines.push(` ${i + 1}. ${statusIcon} ${quest.title}`);
9202
- if (quest.subQuests.length > 0) {
9203
- quest.subQuests.forEach((sq) => {
9204
- const sqIcon = this.getStatusIcon(sq.status);
9205
- lines.push(` ${sqIcon} ${sq.title}`);
9206
- });
9207
- }
9208
- });
9209
- lines.push("");
9210
- return lines.join("\n");
9211
- }
9212
- formatStatus(status) {
9213
- switch (status) {
9214
- case "planning":
9215
- return "\u{1F4CB} Planning";
9216
- case "in_progress":
9217
- return "\u{1F504} In Progress";
9218
- case "completed":
9219
- return "\u2705 Completed";
9220
- case "cancelled":
9221
- return "\u274C Cancelled";
9222
- default:
9223
- return status;
9224
- }
9225
- }
9226
- getStatusIcon(status) {
9227
- switch (status) {
9228
- case "pending":
9229
- return "\u2B1C";
9230
- case "in_progress":
9231
- return "\u{1F504}";
9232
- case "completed":
9233
- return "\u2705";
9234
- case "skipped":
9235
- return "\u23ED\uFE0F";
9236
- default:
9237
- return "\u2B1C";
9238
- }
9239
- }
9240
- };
9241
-
9242
9047
  // src/llm/ServerLlmBackend.ts
9243
9048
  import { createParser } from "eventsource-parser";
9244
9049
  import { isAxiosError } from "axios";
@@ -9438,9 +9243,32 @@ var ServerLlmBackend = class {
9438
9243
  }
9439
9244
  /**
9440
9245
  * Get available models from server
9441
- * For now, returns hardcoded list of supported models
9246
+ * Fetches from /api/models and filters for CLI-compatible models
9247
+ * Falls back to hardcoded list if API fails
9442
9248
  */
9443
9249
  async getModelInfo() {
9250
+ try {
9251
+ logger.debug("[ServerLlmBackend] Fetching models from /api/models");
9252
+ const response = await this.apiClient.get("/api/models");
9253
+ const filteredModels = response.models.filter((model) => model.type === "text" && model.supportsTools === true);
9254
+ logger.debug(`[ServerLlmBackend] Fetched ${filteredModels.length} CLI-compatible models`);
9255
+ if (filteredModels.length === 0) {
9256
+ logger.warn("[ServerLlmBackend] No CLI-compatible models found from API, using fallback");
9257
+ return this.getFallbackModels();
9258
+ }
9259
+ return filteredModels;
9260
+ } catch (error) {
9261
+ logger.warn(
9262
+ `[ServerLlmBackend] Failed to fetch models from API, using fallback: ${error instanceof Error ? error.message : String(error)}`
9263
+ );
9264
+ return this.getFallbackModels();
9265
+ }
9266
+ }
9267
+ /**
9268
+ * Fallback models when API is unavailable
9269
+ * Returns hardcoded list of commonly supported models
9270
+ */
9271
+ getFallbackModels() {
9444
9272
  return [
9445
9273
  {
9446
9274
  id: "claude-sonnet-4-5-20250929",
@@ -9625,7 +9453,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
9625
9453
  // package.json
9626
9454
  var package_default = {
9627
9455
  name: "@bike4mind/cli",
9628
- version: "0.2.4-feat-questmaster-external-integrations.17096+6c1c5e891",
9456
+ version: "0.2.5-feat-cli-dynamic-model-fetching.17089+db1b07944",
9629
9457
  type: "module",
9630
9458
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9631
9459
  license: "UNLICENSED",
@@ -9727,10 +9555,10 @@ var package_default = {
9727
9555
  },
9728
9556
  devDependencies: {
9729
9557
  "@bike4mind/agents": "0.1.0",
9730
- "@bike4mind/common": "2.37.1-feat-questmaster-external-integrations.17096+6c1c5e891",
9731
- "@bike4mind/mcp": "1.19.5-feat-questmaster-external-integrations.17096+6c1c5e891",
9732
- "@bike4mind/services": "2.32.1-feat-questmaster-external-integrations.17096+6c1c5e891",
9733
- "@bike4mind/utils": "2.1.1-feat-questmaster-external-integrations.17096+6c1c5e891",
9558
+ "@bike4mind/common": "2.37.1-feat-cli-dynamic-model-fetching.17089+db1b07944",
9559
+ "@bike4mind/mcp": "1.19.6-feat-cli-dynamic-model-fetching.17089+db1b07944",
9560
+ "@bike4mind/services": "2.32.2-feat-cli-dynamic-model-fetching.17089+db1b07944",
9561
+ "@bike4mind/utils": "2.1.1-feat-cli-dynamic-model-fetching.17089+db1b07944",
9734
9562
  "@types/diff": "^5.0.9",
9735
9563
  "@types/jsonwebtoken": "^9.0.4",
9736
9564
  "@types/node": "^22.9.0",
@@ -9742,7 +9570,7 @@ var package_default = {
9742
9570
  typescript: "^5.9.3",
9743
9571
  vitest: "^3.2.4"
9744
9572
  },
9745
- gitHead: "6c1c5e891a0b609968c2abb5a22b602af8f2a864"
9573
+ gitHead: "db1b079442c65e5ec9a8c27df0190d14e6950889"
9746
9574
  };
9747
9575
 
9748
9576
  // src/config/constants.ts
@@ -10025,8 +9853,10 @@ Remember: Use context from previous messages to understand follow-up questions.`
10025
9853
  agent,
10026
9854
  mcpManager,
10027
9855
  permissionManager,
10028
- config
9856
+ config,
10029
9857
  // Store config for synchronous access
9858
+ availableModels: models
9859
+ // Store models for ConfigEditor
10030
9860
  }));
10031
9861
  setStoreSession(newSession);
10032
9862
  setIsInitialized(true);
@@ -10416,176 +10246,6 @@ No usage data available for the last ${USAGE_DAYS} days.`);
10416
10246
  console.log("");
10417
10247
  break;
10418
10248
  }
10419
- case "quest":
10420
- case "q": {
10421
- const questPlanId = args[0];
10422
- if (!questPlanId) {
10423
- console.log("\nUsage: /quest <quest-plan-id>");
10424
- console.log("Example: /quest abc123");
10425
- console.log("\nThis will load a quest plan into your current session.\n");
10426
- break;
10427
- }
10428
- const questAuthTokens = await state.configStore.getAuthTokens();
10429
- if (!questAuthTokens || new Date(questAuthTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
10430
- console.log("\n\u274C Authentication required. Run /login first.\n");
10431
- break;
10432
- }
10433
- console.log("\nLoading quest plan...");
10434
- try {
10435
- const config = await state.configStore.get();
10436
- const apiBaseURL = getApiUrl(config.apiConfig);
10437
- const apiClient = new ApiClient(apiBaseURL, state.configStore);
10438
- const questTracker = new QuestTracker(apiClient);
10439
- const questPlan = await questTracker.fetchQuestPlan(questPlanId);
10440
- if (!questPlan) {
10441
- console.log("\n\u274C Quest plan not found.\n");
10442
- break;
10443
- }
10444
- const questLink = questTracker.createQuestLink(questPlan);
10445
- const updatedSession = {
10446
- ...state.session,
10447
- quest: questLink,
10448
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10449
- };
10450
- setState((prev) => ({ ...prev, session: updatedSession }));
10451
- setStoreSession(updatedSession);
10452
- await state.sessionStore.save(updatedSession);
10453
- console.log(`
10454
- \u2705 Quest loaded: ${questPlan.goal}`);
10455
- console.log(questTracker.formatQuestPlan(questPlan));
10456
- } catch (error) {
10457
- if (isAxiosError2(error)) {
10458
- if (error.response?.status === 404) {
10459
- console.log("\n\u274C Quest plan not found.\n");
10460
- } else if (error.response?.status === 403) {
10461
- console.log("\n\u274C Access denied to this quest plan.\n");
10462
- } else {
10463
- console.log(`
10464
- \u274C Error loading quest: ${error.message}
10465
- `);
10466
- }
10467
- } else if (error instanceof Error) {
10468
- console.log(`
10469
- \u274C Error: ${error.message}
10470
- `);
10471
- }
10472
- }
10473
- break;
10474
- }
10475
- case "quest-status":
10476
- case "qs": {
10477
- if (!state.session?.quest) {
10478
- console.log("\n\u26A0\uFE0F No quest linked to this session.");
10479
- console.log("Use /quest <quest-id> to load a quest.\n");
10480
- break;
10481
- }
10482
- const questLink = state.session.quest;
10483
- console.log("\n\u{1F3AF} Current Quest Status:");
10484
- console.log(` Plan: ${questLink.questPlanName}`);
10485
- if (questLink.questTitle) {
10486
- console.log(` Quest: ${questLink.questTitle}`);
10487
- }
10488
- console.log(` Progress: ${questLink.progress.completed}/${questLink.progress.total}`);
10489
- console.log(
10490
- ` Sync: ${questLink.syncStatus === "synced" ? "\u2705 Synced" : questLink.syncStatus === "pending" ? "\u23F3 Pending" : "\u26A0\uFE0F Offline"}`
10491
- );
10492
- if (questLink.lastSyncedAt) {
10493
- console.log(` Last Synced: ${new Date(questLink.lastSyncedAt).toLocaleString()}`);
10494
- }
10495
- try {
10496
- const config = await state.configStore.get();
10497
- const apiBaseURL = getApiUrl(config.apiConfig);
10498
- const apiClient = new ApiClient(apiBaseURL, state.configStore);
10499
- const questTracker = new QuestTracker(apiClient);
10500
- const questPlan = await questTracker.fetchQuestPlan(questLink.questPlanId);
10501
- if (questPlan) {
10502
- console.log(questTracker.formatQuestPlan(questPlan));
10503
- const updatedLink = questTracker.updateProgress(questLink, questPlan);
10504
- if (updatedLink.progress.completed !== questLink.progress.completed || updatedLink.progress.total !== questLink.progress.total) {
10505
- const updatedSession = {
10506
- ...state.session,
10507
- quest: updatedLink,
10508
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10509
- };
10510
- setState((prev) => ({ ...prev, session: updatedSession }));
10511
- setStoreSession(updatedSession);
10512
- await state.sessionStore.save(updatedSession);
10513
- }
10514
- }
10515
- } catch {
10516
- console.log("\n\u26A0\uFE0F Could not fetch latest quest data (showing cached info).\n");
10517
- }
10518
- break;
10519
- }
10520
- case "quest-unlink": {
10521
- if (!state.session?.quest) {
10522
- console.log("\n\u26A0\uFE0F No quest linked to this session.\n");
10523
- break;
10524
- }
10525
- const questName = state.session.quest.questPlanName;
10526
- const updatedSession = {
10527
- ...state.session,
10528
- quest: void 0,
10529
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10530
- };
10531
- setState((prev) => ({ ...prev, session: updatedSession }));
10532
- setStoreSession(updatedSession);
10533
- await state.sessionStore.save(updatedSession);
10534
- console.log(`
10535
- \u2705 Unlinked quest: ${questName}
10536
- `);
10537
- break;
10538
- }
10539
- case "plan": {
10540
- const planAuthTokens = await state.configStore.getAuthTokens();
10541
- if (!planAuthTokens || new Date(planAuthTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
10542
- console.log("\n\u274C Authentication required. Run /login first.\n");
10543
- break;
10544
- }
10545
- if (!state.session || state.session.messages.length === 0) {
10546
- console.log("\n\u26A0\uFE0F No conversation context to create a plan from.");
10547
- console.log("Start a conversation first, then use /plan to generate a QuestMaster plan.\n");
10548
- break;
10549
- }
10550
- console.log("\n\u{1F3AF} Creating QuestMaster plan from conversation context...");
10551
- console.log("\u{1F4A1} This will analyze your conversation and create a structured plan.\n");
10552
- try {
10553
- const config = await state.configStore.get();
10554
- const apiBaseURL = getApiUrl(config.apiConfig);
10555
- const apiClient = new ApiClient(apiBaseURL, state.configStore);
10556
- const contextMessages = state.session.messages.slice(-10).map((m) => ({
10557
- role: m.role,
10558
- content: m.content
10559
- }));
10560
- const response = await apiClient.post("/api/quest-plans", {
10561
- context: contextMessages,
10562
- sessionId: state.session.id
10563
- });
10564
- if (!response.success) {
10565
- console.log(`
10566
- \u274C Failed to create plan: ${response.error}
10567
- `);
10568
- break;
10569
- }
10570
- console.log(`
10571
- \u2705 Quest plan created: ${response.questPlan.goal}`);
10572
- console.log(` Plan ID: ${response.questPlan.id}`);
10573
- console.log(`
10574
- \u{1F4A1} Use /quest ${response.questPlan.id} to load this plan into your session.
10575
- `);
10576
- } catch (error) {
10577
- if (isAxiosError2(error)) {
10578
- console.log(`
10579
- \u274C Error creating plan: ${error.response?.data?.error || error.message}
10580
- `);
10581
- } else if (error instanceof Error) {
10582
- console.log(`
10583
- \u274C Error: ${error.message}
10584
- `);
10585
- }
10586
- }
10587
- break;
10588
- }
10589
10249
  default:
10590
10250
  console.log(`Unknown command: /${command}`);
10591
10251
  console.log("Type /help for available commands");
@@ -10632,6 +10292,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
10632
10292
  onCommand: handleCommand,
10633
10293
  commandHistory,
10634
10294
  config: state.config,
10295
+ availableModels: state.availableModels,
10635
10296
  onSaveConfig: handleSaveConfig,
10636
10297
  onPermissionResponse: (response) => {
10637
10298
  if (state.permissionPrompt) {