diff --git a/.env.example b/.env.example index cd20ca72a..fb9ee8398 100644 --- a/.env.example +++ b/.env.example @@ -216,6 +216,8 @@ ANDROID_SHA256_CERT_FINGERPRINT=AC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38: # ENABLE_RACK_ATTACK=true # RACK_ATTACK_LIMIT=300 # ENABLE_RACK_ATTACK_WIDGET_API=true +# Comma-separated list of trusted IPs that bypass Rack Attack throttling rules +# RACK_ATTACK_ALLOWED_IPS=127.0.0.1,::1,192.168.0.10 ## Running chatwoot as an API only server ## setting this value to true will disable the frontend dashboard endpoints diff --git a/.gitignore b/.gitignore index 53deb62a8..c64fb5c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -71,9 +71,6 @@ test/cypress/videos/* /config/master.key /config/*.enc -#ignore files under .vscode directory -.vscode -.cursor # yalc for local testing .yalc @@ -92,5 +89,8 @@ yarn-debug.log* # https://vitejs.dev/guide/env-and-mode.html#env-files *.local -# Claude.ai config file -CLAUDE.md + +# TextEditors & AI Agents config files +.vscode +.claude/settings.local.json +.cursor diff --git a/.windsurf/rules/chatwoot.md b/.windsurf/rules/chatwoot.md new file mode 120000 index 000000000..b7e6491d3 --- /dev/null +++ b/.windsurf/rules/chatwoot.md @@ -0,0 +1 @@ +../../AGENTS.md \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..ad374799c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,58 @@ +# Chatwoot Development Guidelines + +## Build / Test / Lint + +- **Setup**: `bundle install && pnpm install` +- **Run Dev**: `pnpm dev` or `overmind start -f ./Procfile.dev` +- **Lint JS/Vue**: `pnpm eslint` / `pnpm eslint:fix` +- **Lint Ruby**: `bundle exec rubocop -a` +- **Test JS**: `pnpm test` or `pnpm test:watch` +- **Test Ruby**: `bundle exec rspec spec/path/to/file_spec.rb` +- **Single Test**: `bundle exec rspec spec/path/to/file_spec.rb:LINE_NUMBER` +- **Run Project**: `overmind start -f Procfile.dev` + +## Code Style + +- **Ruby**: Follow RuboCop rules (150 character max line length) +- **Vue/JS**: Use ESLint (Airbnb base + Vue 3 recommended) +- **Vue Components**: Use PascalCase +- **Events**: Use camelCase +- **I18n**: No bare strings in templates; use i18n +- **Error Handling**: Use custom exceptions (`lib/custom_exceptions/`) +- **Models**: Validate presence/uniqueness, add proper indexes +- **Type Safety**: Use PropTypes in Vue, strong params in Rails +- **Naming**: Use clear, descriptive names with consistent casing +- **Vue API**: Always use Composition API with ` + + diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue index 249051878..362950802 100644 --- a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue +++ b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/EditAssistantForm.vue @@ -100,7 +100,10 @@ const handleBasicInfoUpdate = async () => { const payload = { name: state.name, description: state.description, - product_name: state.productName, + config: { + ...props.assistant.config, + product_name: state.productName, + }, }; emit('submit', payload); diff --git a/app/javascript/dashboard/components-next/dialog/Dialog.vue b/app/javascript/dashboard/components-next/dialog/Dialog.vue index 6800b1254..78ca5206b 100644 --- a/app/javascript/dashboard/components-next/dialog/Dialog.vue +++ b/app/javascript/dashboard/components-next/dialog/Dialog.vue @@ -2,9 +2,9 @@ import { ref, computed } from 'vue'; import { OnClickOutside } from '@vueuse/components'; import { useI18n } from 'vue-i18n'; -import { useMapGetter } from 'dashboard/composables/store.js'; import Button from 'dashboard/components-next/button/Button.vue'; +import TeleportWithDirection from 'dashboard/components-next/TeleportWithDirection.vue'; const props = defineProps({ type: { @@ -59,8 +59,6 @@ const emit = defineEmits(['confirm', 'close']); const { t } = useI18n(); -const isRTL = useMapGetter('accounts/isRTL'); - const dialogRef = ref(null); const dialogContentRef = ref(null); @@ -94,7 +92,7 @@ defineExpose({ open, close });