@vibeship/devtools
Version:
Comprehensive markdown-based project management system with AI capabilities for Next.js applications
1 lines • 1.31 MB
Source Map (JSON)
{"version":3,"sources":["../src/contexts/VibeshipContext.tsx","../src/providers/ErrorBoundary.tsx","../src/providers/LoadingSpinner.tsx","../src/services/security/encryption-service.ts","../src/services/security/api-key-manager.ts","../src/services/settings/ai-settings-store.ts","../src/contexts/AISettingsContext.tsx","../../../node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs","../../../node_modules/framer-motion/dist/es/utils/use-constant.mjs","../../../node_modules/framer-motion/dist/es/context/PresenceContext.mjs","../../../node_modules/framer-motion/dist/es/context/MotionConfigContext.mjs","../../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs","../../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs","../../../node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs","../../../node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs","../../../node_modules/framer-motion/dist/es/utils/is-browser.mjs","../../../node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs","../../../node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs","../../../node_modules/motion-utils/dist/es/noop.mjs","../../../node_modules/motion-utils/dist/es/errors.mjs","../../../node_modules/motion-utils/dist/es/memo.mjs","../../../node_modules/motion-utils/dist/es/progress.mjs","../../../node_modules/motion-utils/dist/es/time-conversion.mjs","../../../node_modules/motion-utils/dist/es/index.mjs","../../../node_modules/framer-motion/dist/es/utils/GlobalConfig.mjs","../../../node_modules/framer-motion/dist/es/frameloop/render-step.mjs","../../../node_modules/framer-motion/dist/es/frameloop/batcher.mjs","../../../node_modules/framer-motion/dist/es/frameloop/frame.mjs","../../../node_modules/framer-motion/dist/es/context/LazyContext.mjs","../../../node_modules/framer-motion/dist/es/motion/features/definitions.mjs","../../../node_modules/framer-motion/dist/es/motion/features/load-features.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/valid-prop.mjs","../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js","../../../node_modules/framer-motion/dist/es/render/dom/utils/filter-props.mjs","../../../node_modules/framer-motion/dist/es/utils/warn-once.mjs","../../../node_modules/framer-motion/dist/es/render/components/create-proxy.mjs","../../../node_modules/framer-motion/dist/es/context/MotionContext/index.mjs","../../../node_modules/framer-motion/dist/es/render/utils/is-variant-label.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/is-animation-controls.mjs","../../../node_modules/framer-motion/dist/es/render/utils/variant-props.mjs","../../../node_modules/framer-motion/dist/es/render/utils/is-controlling-variants.mjs","../../../node_modules/framer-motion/dist/es/context/MotionContext/utils.mjs","../../../node_modules/framer-motion/dist/es/context/MotionContext/create.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/symbol.mjs","../../../node_modules/framer-motion/dist/es/utils/is-ref-object.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/camel-to-dash.mjs","../../../node_modules/framer-motion/dist/es/animation/optimized-appear/data-id.mjs","../../../node_modules/framer-motion/dist/es/frameloop/microtask.mjs","../../../node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/use-visual-element.mjs","../../../node_modules/framer-motion/dist/es/motion/index.mjs","../../../node_modules/framer-motion/dist/es/render/svg/lowercase-elements.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/is-svg-component.mjs","../../../node_modules/framer-motion/dist/es/render/utils/resolve-variants.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/is-keyframes-target.mjs","../../../node_modules/framer-motion/dist/es/utils/resolve-value.mjs","../../../node_modules/framer-motion/dist/es/value/utils/is-motion-value.mjs","../../../node_modules/framer-motion/dist/es/value/utils/resolve-motion-value.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/use-visual-state.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/keys-transform.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/is-css-variable.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/get-as-type.mjs","../../../node_modules/framer-motion/dist/es/utils/clamp.mjs","../../../node_modules/framer-motion/dist/es/value/types/numbers/index.mjs","../../../node_modules/framer-motion/dist/es/value/types/numbers/units.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/number-browser.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/transform.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/type-int.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/number.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/build-transform.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/build-styles.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/path.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/transform-origin.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/build-attrs.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/create-render-state.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/create-render-state.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/is-svg-tag.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/render.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/camel-case-attrs.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/render.mjs","../../../node_modules/framer-motion/dist/es/projection/styles/scale-correction.mjs","../../../node_modules/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/scrape-motion-values.mjs","../../../node_modules/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs","../../../node_modules/framer-motion/dist/es/render/svg/config-motion.mjs","../../../node_modules/framer-motion/dist/es/render/html/config-motion.mjs","../../../node_modules/framer-motion/dist/es/render/html/use-props.mjs","../../../node_modules/framer-motion/dist/es/render/svg/use-props.mjs","../../../node_modules/framer-motion/dist/es/render/dom/use-render.mjs","../../../node_modules/framer-motion/dist/es/render/components/create-factory.mjs","../../../node_modules/framer-motion/dist/es/utils/shallow-compare.mjs","../../../node_modules/framer-motion/dist/es/render/utils/resolve-dynamic-variants.mjs","../../../node_modules/motion-dom/dist/es/utils/supports/scroll-timeline.mjs","../../../node_modules/motion-dom/dist/es/animation/controls/BaseGroup.mjs","../../../node_modules/motion-dom/dist/es/animation/controls/Group.mjs","../../../node_modules/motion-dom/dist/es/animation/utils/get-value-transition.mjs","../../../node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.mjs","../../../node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs","../../../node_modules/motion-dom/dist/es/animation/generators/utils/is-generator.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/utils/attach-timeline.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/NativeAnimationControls.mjs","../../../node_modules/motion-dom/dist/es/utils/is-bezier-definition.mjs","../../../node_modules/motion-dom/dist/es/utils/supports/flags.mjs","../../../node_modules/motion-dom/dist/es/utils/supports/memo.mjs","../../../node_modules/motion-dom/dist/es/utils/supports/linear-easing.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/utils/linear.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/utils/easing.mjs","../../../node_modules/motion-dom/dist/es/gestures/drag/state/is-active.mjs","../../../node_modules/motion-dom/dist/es/utils/resolve-elements.mjs","../../../node_modules/motion-dom/dist/es/gestures/utils/setup.mjs","../../../node_modules/motion-dom/dist/es/gestures/hover.mjs","../../../node_modules/motion-dom/dist/es/gestures/utils/is-node-or-child.mjs","../../../node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.mjs","../../../node_modules/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.mjs","../../../node_modules/motion-dom/dist/es/gestures/press/utils/state.mjs","../../../node_modules/motion-dom/dist/es/gestures/press/utils/keyboard.mjs","../../../node_modules/motion-dom/dist/es/gestures/press/index.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/utils/convert-options.mjs","../../../node_modules/motion-dom/dist/es/animation/waapi/PseudoAnimation.mjs","../../../node_modules/motion-dom/dist/es/view/utils/choose-layer-type.mjs","../../../node_modules/motion-dom/dist/es/view/utils/css.mjs","../../../node_modules/motion-dom/dist/es/view/utils/get-layer-name.mjs","../../../node_modules/motion-dom/dist/es/view/utils/get-view-animations.mjs","../../../node_modules/motion-dom/dist/es/view/utils/has-target.mjs","../../../node_modules/motion-dom/dist/es/view/start.mjs","../../../node_modules/motion-dom/dist/es/view/index.mjs","../../../node_modules/motion-dom/dist/es/gestures/drag/state/set-active.mjs","../../../node_modules/motion-dom/dist/es/index.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/keys-position.mjs","../../../node_modules/framer-motion/dist/es/frameloop/sync-time.mjs","../../../node_modules/framer-motion/dist/es/utils/array.mjs","../../../node_modules/framer-motion/dist/es/utils/subscription-manager.mjs","../../../node_modules/framer-motion/dist/es/utils/velocity-per-second.mjs","../../../node_modules/framer-motion/dist/es/value/index.mjs","../../../node_modules/framer-motion/dist/es/render/utils/setters.mjs","../../../node_modules/framer-motion/dist/es/value/use-will-change/is.mjs","../../../node_modules/framer-motion/dist/es/value/use-will-change/add-will-change.mjs","../../../node_modules/framer-motion/dist/es/animation/optimized-appear/get-appear-id.mjs","../../../node_modules/framer-motion/dist/es/utils/use-instant-transition-state.mjs","../../../node_modules/framer-motion/dist/es/easing/cubic-bezier.mjs","../../../node_modules/framer-motion/dist/es/easing/modifiers/mirror.mjs","../../../node_modules/framer-motion/dist/es/easing/modifiers/reverse.mjs","../../../node_modules/framer-motion/dist/es/easing/back.mjs","../../../node_modules/framer-motion/dist/es/easing/anticipate.mjs","../../../node_modules/framer-motion/dist/es/easing/circ.mjs","../../../node_modules/framer-motion/dist/es/utils/is-zero-value-string.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/is-none.mjs","../../../node_modules/framer-motion/dist/es/value/types/utils/sanitize.mjs","../../../node_modules/framer-motion/dist/es/value/types/utils/float-regex.mjs","../../../node_modules/framer-motion/dist/es/value/types/utils/is-nullish.mjs","../../../node_modules/framer-motion/dist/es/value/types/utils/single-color-regex.mjs","../../../node_modules/framer-motion/dist/es/value/types/color/utils.mjs","../../../node_modules/framer-motion/dist/es/value/types/color/rgba.mjs","../../../node_modules/framer-motion/dist/es/value/types/color/hex.mjs","../../../node_modules/framer-motion/dist/es/value/types/color/hsla.mjs","../../../node_modules/framer-motion/dist/es/value/types/color/index.mjs","../../../node_modules/framer-motion/dist/es/value/types/utils/color-regex.mjs","../../../node_modules/framer-motion/dist/es/value/types/complex/index.mjs","../../../node_modules/framer-motion/dist/es/value/types/complex/filter.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/defaults.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/animatable-none.mjs","../../../node_modules/framer-motion/dist/es/render/html/utils/make-none-animatable.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/unit-conversion.mjs","../../../node_modules/framer-motion/dist/es/render/utils/KeyframesResolver.mjs","../../../node_modules/framer-motion/dist/es/utils/is-numerical-string.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/css-variables-conversion.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/test.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/type-auto.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/dimensions.mjs","../../../node_modules/framer-motion/dist/es/render/dom/DOMKeyframesResolver.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/is-animatable.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/utils/can-animate.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/waapi/utils/get-final-keyframe.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/BaseAnimation.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/number.mjs","../../../node_modules/framer-motion/dist/es/utils/hsla-to-rgba.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/immediate.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/color.mjs","../../../node_modules/framer-motion/dist/es/utils/pipe.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/visibility.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/complex.mjs","../../../node_modules/framer-motion/dist/es/utils/mix/index.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/utils/velocity.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/spring/defaults.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/spring/find.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/spring/index.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/inertia.mjs","../../../node_modules/framer-motion/dist/es/easing/ease.mjs","../../../node_modules/framer-motion/dist/es/easing/utils/is-easing-array.mjs","../../../node_modules/framer-motion/dist/es/easing/utils/map.mjs","../../../node_modules/framer-motion/dist/es/utils/interpolate.mjs","../../../node_modules/framer-motion/dist/es/utils/offsets/fill.mjs","../../../node_modules/framer-motion/dist/es/utils/offsets/default.mjs","../../../node_modules/framer-motion/dist/es/utils/offsets/time.mjs","../../../node_modules/framer-motion/dist/es/animation/generators/keyframes.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/drivers/driver-frameloop.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/utils/accelerated-values.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/waapi/index.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs","../../../node_modules/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/default-transitions.mjs","../../../node_modules/framer-motion/dist/es/animation/utils/is-transition-defined.mjs","../../../node_modules/framer-motion/dist/es/animation/interfaces/motion-value.mjs","../../../node_modules/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs","../../../node_modules/framer-motion/dist/es/animation/interfaces/visual-element-variant.mjs","../../../node_modules/framer-motion/dist/es/animation/interfaces/visual-element.mjs","../../../node_modules/framer-motion/dist/es/render/utils/get-variant-context.mjs","../../../node_modules/framer-motion/dist/es/render/utils/animation-state.mjs","../../../node_modules/framer-motion/dist/es/motion/features/Feature.mjs","../../../node_modules/framer-motion/dist/es/motion/features/animation/index.mjs","../../../node_modules/framer-motion/dist/es/motion/features/animation/exit.mjs","../../../node_modules/framer-motion/dist/es/motion/features/animations.mjs","../../../node_modules/framer-motion/dist/es/events/add-dom-event.mjs","../../../node_modules/framer-motion/dist/es/events/event-info.mjs","../../../node_modules/framer-motion/dist/es/events/add-pointer-event.mjs","../../../node_modules/framer-motion/dist/es/utils/distance.mjs","../../../node_modules/framer-motion/dist/es/gestures/pan/PanSession.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/delta-calc.mjs","../../../node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/models.mjs","../../../node_modules/framer-motion/dist/es/projection/utils/each-axis.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/conversion.mjs","../../../node_modules/framer-motion/dist/es/projection/utils/has-transform.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/delta-apply.mjs","../../../node_modules/framer-motion/dist/es/projection/utils/measure.mjs","../../../node_modules/framer-motion/dist/es/utils/get-context-window.mjs","../../../node_modules/framer-motion/dist/es/gestures/drag/VisualElementDragControls.mjs","../../../node_modules/framer-motion/dist/es/gestures/drag/index.mjs","../../../node_modules/framer-motion/dist/es/gestures/pan/index.mjs","../../../node_modules/framer-motion/dist/es/projection/node/state.mjs","../../../node_modules/framer-motion/dist/es/projection/styles/scale-border-radius.mjs","../../../node_modules/framer-motion/dist/es/projection/styles/scale-box-shadow.mjs","../../../node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.mjs","../../../node_modules/framer-motion/dist/es/animation/animate/single-value.mjs","../../../node_modules/framer-motion/dist/es/render/dom/utils/is-svg-element.mjs","../../../node_modules/framer-motion/dist/es/render/utils/compare-by-depth.mjs","../../../node_modules/framer-motion/dist/es/render/utils/flat-tree.mjs","../../../node_modules/framer-motion/dist/es/utils/delay.mjs","../../../node_modules/framer-motion/dist/es/projection/animation/mix-values.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/copy.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/delta-remove.mjs","../../../node_modules/framer-motion/dist/es/projection/geometry/utils.mjs","../../../node_modules/framer-motion/dist/es/projection/shared/stack.mjs","../../../node_modules/framer-motion/dist/es/projection/styles/transform.mjs","../../../node_modules/framer-motion/dist/es/projection/node/create-projection-node.mjs","../../../node_modules/framer-motion/dist/es/projection/node/DocumentProjectionNode.mjs","../../../node_modules/framer-motion/dist/es/projection/node/HTMLProjectionNode.mjs","../../../node_modules/framer-motion/dist/es/motion/features/drag.mjs","../../../node_modules/framer-motion/dist/es/gestures/hover.mjs","../../../node_modules/framer-motion/dist/es/gestures/focus.mjs","../../../node_modules/framer-motion/dist/es/gestures/press.mjs","../../../node_modules/framer-motion/dist/es/motion/features/viewport/observers.mjs","../../../node_modules/framer-motion/dist/es/motion/features/viewport/index.mjs","../../../node_modules/framer-motion/dist/es/motion/features/gestures.mjs","../../../node_modules/framer-motion/dist/es/motion/features/layout.mjs","../../../node_modules/framer-motion/dist/es/utils/reduced-motion/state.mjs","../../../node_modules/framer-motion/dist/es/utils/reduced-motion/index.mjs","../../../node_modules/framer-motion/dist/es/render/dom/value-types/find.mjs","../../../node_modules/framer-motion/dist/es/render/store.mjs","../../../node_modules/framer-motion/dist/es/render/utils/motion-values.mjs","../../../node_modules/framer-motion/dist/es/render/VisualElement.mjs","../../../node_modules/framer-motion/dist/es/render/dom/DOMVisualElement.mjs","../../../node_modules/framer-motion/dist/es/render/html/HTMLVisualElement.mjs","../../../node_modules/framer-motion/dist/es/render/svg/SVGVisualElement.mjs","../../../node_modules/framer-motion/dist/es/render/dom/create-visual-element.mjs","../../../node_modules/framer-motion/dist/es/render/components/motion/create.mjs","../../../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs","../../../node_modules/framer-motion/dist/es/index.mjs","../src/components/ai-settings/ProviderSelector.tsx","../src/components/ai-settings/ModelConfigurator.tsx","../src/components/ai-settings/APIKeyManager.tsx","../src/components/ai-settings/AdvancedSettings.tsx","../src/components/ai-settings/MCPConfiguration.tsx","../src/components/ai-settings/SettingsImportExport.tsx","../src/components/AISettingsPanel.tsx","../src/utils/logger.ts","../src/providers/VibeshipProviderWithDeps.tsx","../src/utils/KeyboardHandlerManager.ts","../src/providers/VibeshipDevTools.tsx","../src/providers/VibeshipProvider.tsx","../../../node_modules/secure-json-parse/index.js","../src/types/index.ts","../src/index.ts","../src/providers/VibeshipServerProvider.tsx","../src/providers/VibeshipClientProvider.tsx","../src/config/defaults.ts","../src/config/merger.ts","../src/services/ai/types.ts","../src/services/ai/provider-registry.ts","../src/services/ai/config.ts","../../../node_modules/@ai-sdk/provider/src/errors/ai-sdk-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/api-call-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/empty-response-body-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/get-error-message.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-argument-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-prompt-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/invalid-response-data-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/json-parse-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/load-api-key-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/load-setting-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/no-content-generated-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/no-such-model-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/too-many-embedding-values-for-call-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/type-validation-error.ts","../../../node_modules/@ai-sdk/provider/src/errors/unsupported-functionality-error.ts","../../../node_modules/@ai-sdk/provider/src/json-value/is-json.ts","../../../node_modules/@ai-sdk/provider-utils/node_modules/nanoid/non-secure/index.js","../../../node_modules/@ai-sdk/provider-utils/src/combine-headers.ts","../../../node_modules/@ai-sdk/provider-utils/src/convert-async-iterator-to-readable-stream.ts","../../../node_modules/@ai-sdk/provider-utils/src/delay.ts","../../../node_modules/@ai-sdk/provider-utils/src/event-source-parser-stream.ts","../../../node_modules/@ai-sdk/provider-utils/src/extract-response-headers.ts","../../../node_modules/@ai-sdk/provider-utils/src/generate-id.ts","../../../node_modules/@ai-sdk/provider-utils/src/get-error-message.ts","../../../node_modules/@ai-sdk/provider-utils/src/get-from-api.ts","../../../node_modules/@ai-sdk/provider-utils/src/remove-undefined-entries.ts","../../../node_modules/@ai-sdk/provider-utils/src/is-abort-error.ts","../../../node_modules/@ai-sdk/provider-utils/src/load-api-key.ts","../../../node_modules/@ai-sdk/provider-utils/src/load-optional-setting.ts","../../../node_modules/@ai-sdk/provider-utils/src/load-setting.ts","../../../node_modules/@ai-sdk/provider-utils/src/parse-json.ts","../../../node_modules/@ai-sdk/provider-utils/src/validate-types.ts","../../../node_modules/@ai-sdk/provider-utils/src/validator.ts","../../../node_modules/@ai-sdk/provider-utils/src/parse-provider-options.ts","../../../node_modules/@ai-sdk/provider-utils/src/post-to-api.ts","../../../node_modules/@ai-sdk/provider-utils/src/resolve.ts","../../../node_modules/@ai-sdk/provider-utils/src/response-handler.ts","../../../node_modules/@ai-sdk/provider-utils/src/uint8-utils.ts","../../../node_modules/@ai-sdk/provider-utils/src/without-trailing-slash.ts","../../../node_modules/@ai-sdk/openai/src/openai-provider.ts","../../../node_modules/@ai-sdk/openai/src/openai-chat-language-model.ts","../../../node_modules/@ai-sdk/openai/src/convert-to-openai-chat-messages.ts","../../../node_modules/@ai-sdk/openai/src/map-openai-chat-logprobs.ts","../../../node_modules/@ai-sdk/openai/src/map-openai-finish-reason.ts","../../../node_modules/@ai-sdk/openai/src/openai-error.ts","../../../node_modules/@ai-sdk/openai/src/get-response-metadata.ts","../../../node_modules/@ai-sdk/openai/src/openai-prepare-tools.ts","../../../node_modules/@ai-sdk/openai/src/openai-completion-language-model.ts","../../../node_modules/@ai-sdk/openai/src/convert-to-openai-completion-prompt.ts","../../../node_modules/@ai-sdk/openai/src/map-openai-completion-logprobs.ts","../../../node_modules/@ai-sdk/openai/src/openai-embedding-model.ts","../../../node_modules/@ai-sdk/openai/src/openai-image-model.ts","../../../node_modules/@ai-sdk/openai/src/openai-image-settings.ts","../../../node_modules/@ai-sdk/openai/src/openai-transcription-model.ts","../../../node_modules/@ai-sdk/openai/src/responses/openai-responses-language-model.ts","../../../node_modules/@ai-sdk/openai/src/responses/convert-to-openai-responses-messages.ts","../../../node_modules/@ai-sdk/openai/src/responses/map-openai-responses-finish-reason.ts","../../../node_modules/@ai-sdk/openai/src/responses/openai-responses-prepare-tools.ts","../../../node_modules/@ai-sdk/openai/src/openai-tools.ts","../../../node_modules/@ai-sdk/openai/src/openai-speech-model.ts","../src/services/ai/providers/openai-provider.ts","../../../node_modules/@ai-sdk/anthropic/src/anthropic-provider.ts","../../../node_modules/@ai-sdk/anthropic/src/anthropic-messages-language-model.ts","../../../node_modules/@ai-sdk/anthropic/src/anthropic-error.ts","../../../node_modules/@ai-sdk/anthropic/src/anthropic-prepare-tools.ts","../../../node_modules/@ai-sdk/anthropic/src/convert-to-anthropic-messages-prompt.ts","../../../node_modules/@ai-sdk/anthropic/src/map-anthropic-stop-reason.ts","../../../node_modules/@ai-sdk/anthropic/src/anthropic-tools.ts","../src/services/ai/providers/anthropic-provider.ts","../src/services/ai/providers/xai-provider.ts","../src/services/ai/ai-service.ts"],"sourcesContent":["'use client';\n\nimport React, { createContext, ReactNode } from 'react';\n\n// Browser-safe VibeshipConfig type\nexport interface VibeshipConfig {\n scanPaths: string[];\n include: string[];\n exclude: string[];\n features: {\n ai?: boolean;\n tasks?: boolean;\n fileEditing?: boolean;\n commandPalette?: boolean;\n devtools?: boolean;\n realtime?: boolean;\n markdownPreview?: boolean;\n };\n ui: {\n theme: 'light' | 'dark' | 'system';\n hotkey: string;\n position: string;\n showInProduction: boolean;\n defaultSize?: { width: number; height: number };\n };\n api: {\n basePath: string;\n timeout: number;\n version?: string;\n documentation?: boolean;\n middleware?: any[];\n };\n cache: {\n enabled: boolean;\n ttl: number;\n maxSize: number;\n directory?: string;\n strategy?: string;\n };\n security?: {\n authentication: boolean;\n rateLimit: boolean;\n cors: boolean;\n allowedPaths: string[];\n };\n taskPatterns?: {\n todo: boolean;\n fixme: boolean;\n hack: boolean;\n note: boolean;\n };\n experimental: Record<string, any>;\n}\n\nexport interface VibeshipContextValue {\n config: VibeshipConfig;\n isReady: boolean;\n}\n\nexport const VibeshipContext = createContext<VibeshipContextValue | undefined>(undefined);\n\ninterface VibeshipProviderProps {\n children: ReactNode;\n config?: Partial<VibeshipConfig>;\n}\n\nexport function VibeshipProvider({ children, config = {} }: VibeshipProviderProps) {\n // This would be imported from the actual provider in @vibeship/ui\n // For now, we're creating a minimal version\n const value: VibeshipContextValue = {\n config: {\n scanPaths: config.scanPaths || ['./src', './docs', './tickets'],\n include: config.include || ['**/*.md', '**/*.mdx', '**/*.ts', '**/*.tsx'],\n exclude: config.exclude || ['node_modules', '.next', 'dist'],\n features: {\n tasks: config.features?.tasks ?? true,\n ai: config.features?.ai ?? true,\n realtime: config.features?.realtime ?? true,\n commandPalette: config.features?.commandPalette ?? true,\n fileEditing: config.features?.fileEditing ?? false,\n markdownPreview: config.features?.markdownPreview ?? true,\n ...config.features,\n },\n security: {\n authentication: config.security?.authentication ?? false,\n rateLimit: config.security?.rateLimit ?? true,\n cors: config.security?.cors ?? true,\n allowedPaths: config.security?.allowedPaths || ['./src', './docs'],\n ...config.security,\n },\n taskPatterns: {\n todo: config.taskPatterns?.todo ?? true,\n fixme: config.taskPatterns?.fixme ?? true,\n hack: config.taskPatterns?.hack ?? true,\n note: config.taskPatterns?.note ?? true,\n ...config.taskPatterns,\n },\n ui: {\n theme: config.ui?.theme || 'system',\n position: config.ui?.position || 'bottom-right',\n defaultSize: config.ui?.defaultSize || { width: 400, height: 600 },\n hotkey: config.ui?.hotkey || 'cmd+k',\n showInProduction: config.ui?.showInProduction ?? false,\n ...config.ui,\n },\n api: {\n basePath: config.api?.basePath || '/api/vibecode',\n version: config.api?.version || 'v1',\n documentation: config.api?.documentation ?? true,\n timeout: config.api?.timeout || 30000,\n middleware: config.api?.middleware || [],\n ...config.api,\n },\n cache: {\n enabled: config.cache?.enabled ?? true,\n directory: config.cache?.directory || './.vibeship/cache',\n ttl: config.cache?.ttl || 300,\n maxSize: config.cache?.maxSize || 100,\n strategy: config.cache?.strategy || 'lru',\n ...config.cache,\n },\n experimental: config.experimental || {},\n },\n isReady: true,\n };\n\n return (\n <VibeshipContext.Provider value={value}>\n {children}\n </VibeshipContext.Provider>\n );\n}","'use client';\n\nimport React, { Component, ErrorInfo, ReactNode } from 'react';\n\n/**\n * State for the ErrorBoundary component\n * @public\n */\nexport interface ErrorBoundaryState {\n /** Whether an error has been caught */\n hasError: boolean;\n /** The caught error object */\n error: Error | null;\n /** React error info with component stack */\n errorInfo: ErrorInfo | null;\n}\n\n/**\n * Props for the ErrorBoundary component\n * @public\n */\nexport interface ErrorBoundaryProps {\n /** React children to render when there's no error */\n children: ReactNode;\n /** Custom fallback UI renderer */\n fallback?: (error: Error, errorInfo: ErrorInfo, reset: () => void) => ReactNode;\n /** Callback when error is caught */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** Whether to isolate errors to this boundary */\n isolate?: boolean;\n /** Name for debugging purposes */\n name?: string;\n}\n\n/**\n * Error boundary component that catches JavaScript errors in child components\n * \n * @example\n * ```tsx\n * <ErrorBoundary\n * fallback={(error) => <div>Error: {error.message}</div>}\n * onError={(error) => console.error(error)}\n * >\n * <App />\n * </ErrorBoundary>\n * ```\n * \n * @public\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n // Log error to console in development\n if (process.env.NODE_ENV === 'development') {\n console.error(`[Vibecode ErrorBoundary${this.props.name ? ` - ${this.props.name}` : ''}]:`, error, errorInfo);\n }\n\n // Call custom error handler if provided\n this.props.onError?.(error, errorInfo);\n\n // Update state with error info\n this.setState({\n errorInfo,\n });\n }\n\n reset = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n };\n\n render() {\n if (this.state.hasError && this.state.error && this.state.errorInfo) {\n // Use custom fallback if provided\n if (this.props.fallback) {\n return this.props.fallback(this.state.error, this.state.errorInfo, this.reset);\n }\n\n // Default fallback UI\n return (\n <div className=\"vibecode-error-boundary p-4 border border-red-500 rounded-lg bg-red-50 dark:bg-red-950\">\n <h2 className=\"text-lg font-semibold text-red-700 dark:text-red-300 mb-2\">\n Something went wrong\n </h2>\n <details className=\"text-sm text-red-600 dark:text-red-400\">\n <summary className=\"cursor-pointer mb-2\">Error details</summary>\n <pre className=\"whitespace-pre-wrap overflow-auto p-2 bg-red-100 dark:bg-red-900 rounded\">\n {this.state.error.toString()}\n {this.state.errorInfo.componentStack}\n </pre>\n </details>\n <button\n onClick={this.reset}\n className=\"mt-4 px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition-colors\"\n >\n Try again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Higher-order component that wraps a component with an error boundary\n * \n * @param Component - Component to wrap\n * @param errorBoundaryProps - Props to pass to the ErrorBoundary\n * @returns Wrapped component\n * \n * @example\n * ```tsx\n * const SafeComponent = withErrorBoundary(MyComponent, {\n * onError: (error) => logError(error),\n * fallback: (error) => <ErrorDisplay error={error} />\n * });\n * ```\n * \n * @public\n */\nexport function withErrorBoundary<P extends object>(\n Component: React.ComponentType<P>,\n errorBoundaryProps?: Omit<ErrorBoundaryProps, 'children'>\n) {\n const WrappedComponent = (props: P) => (\n <ErrorBoundary {...errorBoundaryProps}>\n <Component {...props} />\n </ErrorBoundary>\n );\n\n WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;\n\n return WrappedComponent;\n}","'use client';\n\nimport React from 'react';\n\nexport function LoadingSpinner() {\n return (\n <div className=\"vibecode-loading-spinner fixed bottom-4 right-4 p-3 bg-white dark:bg-gray-800 rounded-lg shadow-lg\">\n <div className=\"flex items-center space-x-2\">\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-primary\"></div>\n <span className=\"text-sm text-gray-600 dark:text-gray-400\">\n Loading Vibecode DevTools...\n </span>\n </div>\n </div>\n );\n}","/**\n * Encryption Service\n * Provides encryption and decryption for sensitive data\n */\n\nexport class EncryptionService {\n private algorithm = 'AES-GCM';\n private keyLength = 256;\n private saltLength = 16;\n private ivLength = 12;\n private tagLength = 128;\n private iterations = 100000;\n\n /**\n * Derives a key from a password using PBKDF2\n */\n private async deriveKey(\n password: string,\n salt: Uint8Array\n ): Promise<CryptoKey> {\n const encoder = new TextEncoder();\n const passwordBuffer = encoder.encode(password);\n\n const importedKey = await crypto.subtle.importKey(\n 'raw',\n passwordBuffer,\n 'PBKDF2',\n false,\n ['deriveBits', 'deriveKey']\n );\n\n return crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt,\n iterations: this.iterations,\n hash: 'SHA-256',\n },\n importedKey,\n {\n name: this.algorithm,\n length: this.keyLength,\n },\n false,\n ['encrypt', 'decrypt']\n );\n }\n\n /**\n * Gets or generates the encryption password\n */\n private async getPassword(): Promise<string> {\n if (typeof window === 'undefined') {\n // Server-side: use environment variable\n return process.env.ENCRYPTION_KEY || 'default-dev-key-change-in-production';\n }\n\n // Client-side: use or generate a unique password\n const storageKey = 'vibecode-encryption-id';\n let password = localStorage.getItem(storageKey);\n \n if (!password) {\n // Generate a unique password for this browser\n password = this.generatePassword();\n localStorage.setItem(storageKey, password);\n }\n \n return password;\n }\n\n /**\n * Generates a secure random password\n */\n private generatePassword(): string {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Encrypts a string\n */\n async encrypt(plaintext: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(plaintext);\n\n // Generate random salt and IV\n const salt = crypto.getRandomValues(new Uint8Array(this.saltLength));\n const iv = crypto.getRandomValues(new Uint8Array(this.ivLength));\n\n // Derive key from password\n const password = await this.getPassword();\n const key = await this.deriveKey(password, salt);\n\n // Encrypt the data\n const encrypted = await crypto.subtle.encrypt(\n {\n name: this.algorithm,\n iv,\n tagLength: this.tagLength,\n },\n key,\n data\n );\n\n // Combine salt, iv, and encrypted data\n const combined = new Uint8Array(\n salt.length + iv.length + encrypted.byteLength\n );\n combined.set(salt, 0);\n combined.set(iv, salt.length);\n combined.set(new Uint8Array(encrypted), salt.length + iv.length);\n\n // Convert to base64 for storage\n return btoa(String.fromCharCode.apply(null, Array.from(combined)));\n }\n\n /**\n * Decrypts a string\n */\n async decrypt(ciphertext: string): Promise<string> {\n // Convert from base64\n const combined = Uint8Array.from(atob(ciphertext), c => c.charCodeAt(0));\n\n // Extract salt, iv, and encrypted data\n const salt = combined.slice(0, this.saltLength);\n const iv = combined.slice(this.saltLength, this.saltLength + this.ivLength);\n const encrypted = combined.slice(this.saltLength + this.ivLength);\n\n // Derive key from password\n const password = await this.getPassword();\n const key = await this.deriveKey(password, salt);\n\n // Decrypt the data\n const decrypted = await crypto.subtle.decrypt(\n {\n name: this.algorithm,\n iv,\n tagLength: this.tagLength,\n },\n key,\n encrypted\n );\n\n // Convert back to string\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n }\n\n /**\n * Checks if Web Crypto API is available\n */\n isAvailable(): boolean {\n return typeof crypto !== 'undefined' && crypto.subtle !== undefined;\n }\n}","/**\n * Secure API Key Manager\n * Handles encryption, storage, and retrieval of API keys\n */\n\nimport { EncryptionService } from './encryption-service';\n\nexport interface APIKeyManager {\n store(provider: string, key: string): Promise<void>;\n retrieve(provider: string): Promise<string | null>;\n remove(provider: string): Promise<void>;\n validate(provider: string, key: string): Promise<boolean>;\n rotate(provider: string): Promise<string>;\n listProviders(): Promise<string[]>;\n hasKey(provider: string): Promise<boolean>;\n}\n\nexport interface SecureStorage {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n remove(key: string): Promise<void>;\n list(): Promise<string[]>;\n}\n\n/**\n * Browser-based secure storage using localStorage with encryption\n */\nclass BrowserSecureStorage implements SecureStorage {\n private prefix = 'vibecode-secure-';\n\n async get(key: string): Promise<string | null> {\n if (typeof window === 'undefined') return null;\n return localStorage.getItem(this.prefix + key);\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof window === 'undefined') return;\n localStorage.setItem(this.prefix + key, value);\n }\n\n async remove(key: string): Promise<void> {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(this.prefix + key);\n }\n\n async list(): Promise<string[]> {\n if (typeof window === 'undefined') return [];\n const keys: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(this.prefix)) {\n keys.push(key.substring(this.prefix.length));\n }\n }\n return keys;\n }\n}\n\nexport class SecureAPIKeyManager implements APIKeyManager {\n private encryption: EncryptionService;\n private storage: SecureStorage;\n private keyPrefix = 'api-key-';\n private validationCache = new Map<string, { valid: boolean; timestamp: number }>();\n private cacheTimeout = 5 * 60 * 1000; // 5 minutes\n\n constructor(\n encryption?: EncryptionService,\n storage?: SecureStorage\n ) {\n this.encryption = encryption || new EncryptionService();\n this.storage = storage || new BrowserSecureStorage();\n }\n\n async store(provider: string, key: string): Promise<void> {\n if (!key || !provider) {\n throw new Error('Provider and key are required');\n }\n\n // Validate the key format\n this.validateKeyFormat(provider, key);\n\n let encrypted: string;\n try {\n // Try to use proper encryption if available\n if (typeof window !== 'undefined' && this.encryption.isAvailable()) {\n encrypted = await this.encryption.encrypt(key);\n } else {\n // Fallback to simple base64 for server/non-secure environments\n encrypted = Buffer.from(key).toString('base64');\n }\n } catch (error) {\n console.warn('Encryption failed, using base64:', error);\n encrypted = Buffer.from(key).toString('base64');\n }\n \n // Store the encrypted key\n await this.storage.set(this.keyPrefix + provider, encrypted);\n \n // Clear validation cache for this provider\n this.validationCache.delete(provider);\n }\n\n async retrieve(provider: string): Promise<string | null> {\n console.log(`[APIKeyManager] Retrieving key for ${provider}`);\n const encrypted = await this.storage.get(this.keyPrefix + provider);\n if (!encrypted) {\n console.log(`[APIKeyManager] No encrypted key found for ${provider}`);\n return null;\n }\n\n console.log(`[APIKeyManager] Found encrypted key for ${provider}, attempting to decrypt...`);\n try {\n // For server-side, we need a simpler approach\n // In production, use proper server-side encryption\n if (typeof window === 'undefined') {\n // Server-side: Just base64 decode for now\n const decoded = Buffer.from(encrypted, 'base64').toString('utf-8');\n console.log(`[APIKeyManager] Successfully decoded key for ${provider} (server-side)`);\n return decoded;\n }\n const decrypted = await this.encryption.decrypt(encrypted);\n console.log(`[APIKeyManager] Successfully decrypted key for ${provider} (client-side)`);\n return decrypted;\n } catch (error) {\n console.error('Failed to decrypt API key:', error);\n // Try simple base64 decode as fallback\n try {\n const decoded = Buffer.from(encrypted, 'base64').toString('utf-8');\n console.log(`[APIKeyManager] Used fallback base64 decode for ${provider}`);\n return decoded;\n } catch {\n console.error(`[APIKeyManager] Failed to decode key for ${provider} even with fallback`);\n return null;\n }\n }\n }\n\n async remove(provider: string): Promise<void> {\n await this.storage.remove(this.keyPrefix + provider);\n this.validationCache.delete(provider);\n }\n\n async validate(provider: string, key: string): Promise<boolean> {\n // Check cache first\n const cached = this.validationCache.get(provider);\n if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {\n return cached.valid;\n }\n\n // Perform validation based on provider\n let valid = false;\n \n try {\n switch (provider) {\n case 'openai':\n valid = await this.validateOpenAIKey(key);\n break;\n case 'anthropic':\n valid = await this.validateAnthropicKey(key);\n break;\n case 'xai':\n valid = await this.validateXAIKey(key);\n break;\n default:\n // For custom providers, just check format\n valid = this.isValidKeyFormat(key);\n }\n } catch (error) {\n console.error('Key validation error:', error);\n valid = false;\n }\n\n // Cache the result\n this.validationCache.set(provider, { valid, timestamp: Date.now() });\n \n return valid;\n }\n\n async rotate(provider: string): Promise<string> {\n // In a real implementation, this would call the provider's API to rotate the key\n // For now, we'll just generate a new mock key\n const newKey = this.generateMockKey(provider);\n await this.store(provider, newKey);\n return newKey;\n }\n\n async listProviders(): Promise<string[]> {\n const keys = await this.storage.list();\n return keys\n .filter(key => key.startsWith(this.keyPrefix))\n .map(key => key.substring(this.keyPrefix.length));\n }\n\n async hasKey(provider: string): Promise<boolean> {\n const key = await this.retrieve(provider);\n return key !== null;\n }\n\n // Private validation methods\n private validateKeyFormat(provider: string, key: string): void {\n if (!this.isValidKeyFormat(key)) {\n throw new Error(`Invalid key format for provider: ${provider}`);\n }\n\n // Provider-specific format validation\n switch (provider) {\n case 'openai':\n if (!key.startsWith('sk-') && !key.startsWith('sk-proj-')) {\n throw new Error('OpenAI keys must start with \"sk-\" or \"sk-proj-\"');\n }\n break;\n case 'anthropic':\n if (!key.startsWith('sk-ant-')) {\n throw new Error('Anthropic keys must start with \"sk-ant-\"');\n }\n break;\n }\n }\n\n private isValidKeyFormat(key: string): boolean {\n // Basic validation: non-empty, reasonable length, alphanumeric + common chars\n return /^[a-zA-Z0-9\\-_]{20,}$/.test(key);\n }\n\n private async validateOpenAIKey(key: string): Promise<boolean> {\n try {\n const response = await fetch('https://api.openai.com/v1/models', {\n headers: {\n 'Authorization': `Bearer ${key}`,\n },\n });\n return response.status === 200;\n } catch {\n return false;\n }\n }\n\n private async validateAnthropicKey(key: string): Promise<boolean> {\n // Skip validation on client side due to CORS\n if (typeof window !== 'undefined') {\n console.log('[APIKeyManager] Skipping Anthropic key validation on client side (CORS)');\n // Just do basic format check\n return key.startsWith('sk-ant-') && key.length > 40;\n }\n \n try {\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'x-api-key': key,\n 'anthropic-version': '2023-06-01',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model: 'claude-3-opus-20240229',\n messages: [{ role: 'user', content: 'test' }],\n max_tokens: 1,\n }),\n });\n // 401 means invalid key, 400 or 200 means valid key\n return response.status !== 401;\n } catch {\n return false;\n }\n }\n\n private async validateXAIKey(key: string): Promise<boolean> {\n // XAI validation would go here\n // For now, just validate format\n return this.isValidKeyFormat(key);\n }\n\n private generateMockKey(provider: string): string {\n const prefix = {\n openai: 'sk-proj-',\n anthropic: 'sk-ant-',\n xai: 'xai-',\n }[provider] || 'key-';\n\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let key = prefix;\n for (let i = 0; i < 48; i++) {\n key += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return key;\n }\n}","/**\n * AI Settings Store\n * Manages persistence and migration of AI settings\n */\n\nimport { AISettings } from '@/types/ai-settings';\nimport { SecureAPIKeyManager } from '../security/api-key-manager';\n\nexport interface AISettingsStore {\n load(): Promise<AISettings>;\n save(settings: AISettings): Promise<void>;\n migrate(oldVersion: string): Promise<void>;\n export(): Promise<string>;\n import(data: string): Promise<void>;\n reset(): Promise<void>;\n}\n\nconst DEFAULT_SETTINGS: AISettings = {\n provider: 'openai',\n model: 'gpt-4-turbo-preview',\n apiKeys: {},\n temperature: 0.7,\n max