ideaco 1.1.5
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/.dockerignore +33 -0
- package/.nvmrc +1 -0
- package/ARCHITECTURE.md +394 -0
- package/Dockerfile +50 -0
- package/LICENSE +29 -0
- package/README.md +206 -0
- package/bin/i18n.js +46 -0
- package/bin/ideaco.js +494 -0
- package/deploy.sh +15 -0
- package/docker-compose.yml +30 -0
- package/electron/main.cjs +986 -0
- package/electron/preload.cjs +14 -0
- package/electron/web-backends.cjs +854 -0
- package/jsconfig.json +8 -0
- package/next.config.mjs +34 -0
- package/package.json +134 -0
- package/postcss.config.mjs +6 -0
- package/public/demo/dashboard.png +0 -0
- package/public/demo/employee.png +0 -0
- package/public/demo/messages.png +0 -0
- package/public/demo/office.png +0 -0
- package/public/demo/requirement.png +0 -0
- package/public/logo.jpeg +0 -0
- package/public/logo.png +0 -0
- package/scripts/prepare-electron.js +67 -0
- package/scripts/release.js +76 -0
- package/src/app/api/agents/[agentId]/chat/route.js +70 -0
- package/src/app/api/agents/[agentId]/conversations/route.js +35 -0
- package/src/app/api/agents/[agentId]/route.js +106 -0
- package/src/app/api/avatar/route.js +104 -0
- package/src/app/api/browse-dir/route.js +44 -0
- package/src/app/api/chat/route.js +265 -0
- package/src/app/api/company/factory-reset/route.js +43 -0
- package/src/app/api/company/route.js +82 -0
- package/src/app/api/departments/[deptId]/agents/[agentId]/dismiss/route.js +19 -0
- package/src/app/api/departments/route.js +92 -0
- package/src/app/api/group-chat-loop/events/route.js +70 -0
- package/src/app/api/group-chat-loop/route.js +94 -0
- package/src/app/api/mailbox/route.js +100 -0
- package/src/app/api/messages/route.js +14 -0
- package/src/app/api/providers/[id]/configure/route.js +21 -0
- package/src/app/api/providers/[id]/refresh-cookie/route.js +38 -0
- package/src/app/api/providers/[id]/test-cookie/route.js +28 -0
- package/src/app/api/providers/route.js +11 -0
- package/src/app/api/requirements/route.js +242 -0
- package/src/app/api/secretary/route.js +65 -0
- package/src/app/api/system/cli-backends/route.js +91 -0
- package/src/app/api/system/cron/route.js +110 -0
- package/src/app/api/system/knowledge/route.js +104 -0
- package/src/app/api/system/plugins/route.js +40 -0
- package/src/app/api/system/skills/route.js +46 -0
- package/src/app/api/system/status/route.js +46 -0
- package/src/app/api/talent-market/[profileId]/recall/route.js +22 -0
- package/src/app/api/talent-market/[profileId]/route.js +17 -0
- package/src/app/api/talent-market/route.js +26 -0
- package/src/app/api/teams/route.js +773 -0
- package/src/app/api/ws-files/[departmentId]/file/route.js +27 -0
- package/src/app/api/ws-files/[departmentId]/files/route.js +22 -0
- package/src/app/globals.css +130 -0
- package/src/app/layout.jsx +40 -0
- package/src/app/page.jsx +97 -0
- package/src/components/AgentChatModal.jsx +164 -0
- package/src/components/AgentDetailModal.jsx +425 -0
- package/src/components/AgentSpyModal.jsx +481 -0
- package/src/components/AvatarGrid.jsx +29 -0
- package/src/components/BossProfileModal.jsx +162 -0
- package/src/components/CachedAvatar.jsx +77 -0
- package/src/components/ChatPanel.jsx +219 -0
- package/src/components/ChatShared.jsx +255 -0
- package/src/components/DepartmentDetail.jsx +842 -0
- package/src/components/DepartmentView.jsx +367 -0
- package/src/components/FileReference.jsx +260 -0
- package/src/components/FilesView.jsx +465 -0
- package/src/components/GroupChatView.jsx +799 -0
- package/src/components/Mailbox.jsx +926 -0
- package/src/components/MessagesView.jsx +112 -0
- package/src/components/OnboardingGuide.jsx +209 -0
- package/src/components/OrgTree.jsx +151 -0
- package/src/components/Overview.jsx +391 -0
- package/src/components/PixelOffice.jsx +2281 -0
- package/src/components/ProviderGrid.jsx +551 -0
- package/src/components/ProvidersBoard.jsx +16 -0
- package/src/components/RequirementDetail.jsx +1279 -0
- package/src/components/RequirementsBoard.jsx +187 -0
- package/src/components/SecretarySettings.jsx +295 -0
- package/src/components/SetupWizard.jsx +388 -0
- package/src/components/Sidebar.jsx +169 -0
- package/src/components/SystemMonitor.jsx +808 -0
- package/src/components/TalentMarket.jsx +183 -0
- package/src/components/TeamDetail.jsx +697 -0
- package/src/core/agent/base-agent.js +104 -0
- package/src/core/agent/chat-store.js +602 -0
- package/src/core/agent/cli-agent/backends/claude-code/README.md +52 -0
- package/src/core/agent/cli-agent/backends/claude-code/config.js +27 -0
- package/src/core/agent/cli-agent/backends/codebuddy/README.md +236 -0
- package/src/core/agent/cli-agent/backends/codebuddy/config.js +27 -0
- package/src/core/agent/cli-agent/backends/codex/README.md +51 -0
- package/src/core/agent/cli-agent/backends/codex/config.js +27 -0
- package/src/core/agent/cli-agent/backends/index.js +27 -0
- package/src/core/agent/cli-agent/backends/registry.js +580 -0
- package/src/core/agent/cli-agent/index.js +154 -0
- package/src/core/agent/index.js +60 -0
- package/src/core/agent/llm-agent/client.js +320 -0
- package/src/core/agent/llm-agent/index.js +97 -0
- package/src/core/agent/message-bus.js +211 -0
- package/src/core/agent/session.js +608 -0
- package/src/core/agent/tools.js +596 -0
- package/src/core/agent/web-agent/backends/base-backend.js +180 -0
- package/src/core/agent/web-agent/backends/chatgpt/client.js +146 -0
- package/src/core/agent/web-agent/backends/chatgpt/config.js +148 -0
- package/src/core/agent/web-agent/backends/chatgpt/dom-scripts.js +303 -0
- package/src/core/agent/web-agent/backends/index.js +91 -0
- package/src/core/agent/web-agent/index.js +278 -0
- package/src/core/agent/web-agent/web-client.js +407 -0
- package/src/core/employee/base-employee.js +1088 -0
- package/src/core/employee/index.js +35 -0
- package/src/core/employee/knowledge.js +327 -0
- package/src/core/employee/lifecycle.js +990 -0
- package/src/core/employee/memory/index.js +642 -0
- package/src/core/employee/memory/store.js +143 -0
- package/src/core/employee/performance.js +224 -0
- package/src/core/employee/secretary.js +625 -0
- package/src/core/employee/skills.js +398 -0
- package/src/core/index.js +38 -0
- package/src/core/organization/company.js +2600 -0
- package/src/core/organization/department.js +737 -0
- package/src/core/organization/group-chat-loop.js +264 -0
- package/src/core/organization/index.js +8 -0
- package/src/core/organization/persistence.js +111 -0
- package/src/core/organization/team.js +267 -0
- package/src/core/organization/workforce/hr.js +377 -0
- package/src/core/organization/workforce/providers.js +468 -0
- package/src/core/organization/workforce/role-archetypes.js +805 -0
- package/src/core/organization/workforce/talent-market.js +205 -0
- package/src/core/prompts.js +532 -0
- package/src/core/requirement.js +1789 -0
- package/src/core/system/audit.js +483 -0
- package/src/core/system/cron.js +449 -0
- package/src/core/system/index.js +7 -0
- package/src/core/system/plugin.js +2183 -0
- package/src/core/utils/json-parse.js +188 -0
- package/src/core/workspace.js +239 -0
- package/src/lib/api-i18n.js +211 -0
- package/src/lib/avatar.js +268 -0
- package/src/lib/client-store.js +1025 -0
- package/src/lib/config-validator.js +483 -0
- package/src/lib/format-time.js +22 -0
- package/src/lib/hooks.js +414 -0
- package/src/lib/i18n.js +134 -0
- package/src/lib/paths.js +23 -0
- package/src/lib/store.js +72 -0
- package/src/locales/de.js +393 -0
- package/src/locales/en.js +1054 -0
- package/src/locales/es.js +393 -0
- package/src/locales/fr.js +393 -0
- package/src/locales/ja.js +501 -0
- package/src/locales/ko.js +513 -0
- package/src/locales/zh.js +828 -0
- package/tailwind.config.mjs +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="public/logo.jpeg" alt="IdeaCo" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">IdeaCo</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<b>Run a virtual AI company. Hire employees powered by any LLM. Watch them think, argue, bond, and ship real code.</b>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/badge/Next.js-14-black?logo=next.js" />
|
|
13
|
+
<img src="https://img.shields.io/badge/React-18-blue?logo=react" />
|
|
14
|
+
<img src="https://img.shields.io/badge/Electron-33-9feaf9?logo=electron" />
|
|
15
|
+
<img src="https://img.shields.io/badge/License-MIT-green" />
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="#-quick-start">Quick Start</a> ·
|
|
20
|
+
<a href="#-features">Features</a> ·
|
|
21
|
+
<a href="#-architecture">Architecture</a> ·
|
|
22
|
+
<a href="#-download">Download</a> ·
|
|
23
|
+
<a href="ARCHITECTURE.md">Full Architecture Doc</a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## What is IdeaCo?
|
|
29
|
+
|
|
30
|
+
IdeaCo is not another multi-agent framework. It's an **AI employee management system** — you run a virtual company, hire AI agents as employees, assign tasks, and they collaborate autonomously to produce real deliverables.
|
|
31
|
+
|
|
32
|
+
Each employee has **persistent memory**, a **unique personality**, **social relationships** with coworkers, and can be powered by different backends — from cloud LLMs to local CLI tools like **Claude Code**, **Codex**, and **CodeBuddy**.
|
|
33
|
+
|
|
34
|
+
> The name comes from *Idea Unlimited Company* (金点子无限公司), inspired by Yang Hongying's children's story, playfully turning a "Limited Company" into "Unlimited".
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 🧬 Why IdeaCo?
|
|
39
|
+
|
|
40
|
+
Most agent frameworks create **stateless workflows**. IdeaCo manages **long-living AI employees with memory, personality, and social bonds**.
|
|
41
|
+
|
|
42
|
+
| | Typical Agent Framework | IdeaCo |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| **Agents** | Ephemeral, per-task | Persistent employees with memory & personality |
|
|
45
|
+
| **Memory** | None or simple RAG | Layered: long-term + short-term + social impressions + rolling summary |
|
|
46
|
+
| **Social** | Agents don't know each other | Employees form opinions, track affinity, and remember coworkers |
|
|
47
|
+
| **Orchestration** | DAG / workflow graph | Company org structure — departments, teams, roles |
|
|
48
|
+
| **Backend** | Single LLM | Mix LLMs + CLI tools (Claude Code, Codex, CodeBuddy) |
|
|
49
|
+
| **Autonomy** | Triggered by code | Employees poll, think, decide to speak or stay silent on their own |
|
|
50
|
+
| **Interface** | Code / YAML | Visual — pixel office, group chats, dashboards |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## ✨ Features
|
|
55
|
+
|
|
56
|
+
| Screenshot | Feature | Description |
|
|
57
|
+
|:---:|---|---|
|
|
58
|
+
| <img src="public/demo/dashboard.png" width="280" /> | **Dashboard** | Company overview — departments, employees, budget, requirements, and task forces at a glance |
|
|
59
|
+
| <img src="public/demo/office.png" width="280" /> | **Pixel Office** | Pixel-art virtual office where AI agents wander, work at desks, and show real-time chat bubbles |
|
|
60
|
+
| <img src="public/demo/employee.png" width="280" /> | **Employee Profile** | Detailed card — personality, memory (long/short-term), social relationships, affinity scores, performance, and cost tracking |
|
|
61
|
+
| <img src="public/demo/messages.png" width="280" /> | **Group Chat** | Department chats where agents discuss, debate, and collaborate autonomously with flow-of-thought reasoning |
|
|
62
|
+
| <img src="public/demo/requirement.png" width="280" /> | **Requirements** | Assign tasks to departments — agents auto-decompose, execute with real tools, and produce deliverables |
|
|
63
|
+
|
|
64
|
+
### Key Highlights
|
|
65
|
+
|
|
66
|
+
- 🧠 **Flow-of-Thought** — Each employee reads messages, has an inner monologue, and independently decides whether to reply based on topic saturation, relevance, and anti-spam rules
|
|
67
|
+
- 💾 **Layered Memory** — Long-term memory (facts, preferences), short-term memory (TTL-based), rolling history summaries, and AI-managed memory ops (add/delete)
|
|
68
|
+
- 👥 **Social Memory** — Every employee maintains impressions and affinity scores for coworkers. They remember who helped them, who they disagree with, and who they like
|
|
69
|
+
- 🎭 **12 Personality Archetypes** — From "Chatterbox" to "Zen Slacker" to "Anxious Perfectionist", each employee has a unique voice and behavior pattern
|
|
70
|
+
- 🔌 **Multi-Backend** — Mix cloud LLMs (OpenAI, DeepSeek, Anthropic), CLI tools (Claude Code, Codex, CodeBuddy), and web agents (ChatGPT Web) in one company
|
|
71
|
+
- 🏢 **Org Structure** — Departments, teams, roles, talent market, HR hiring — a complete company simulation
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 🏗 Architecture
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
┌───────────────────────────────────────────────────┐
|
|
79
|
+
│ 👤 User (Boss) │
|
|
80
|
+
├───────────────────────────────────────────────────┤
|
|
81
|
+
│ 🧑💼 Secretary │
|
|
82
|
+
│ Intent Parsing · HR · Task Dispatch · Reports │
|
|
83
|
+
├───────────────────────────────────────────────────┤
|
|
84
|
+
│ 🏢 Organization │
|
|
85
|
+
│ Company · Department · Team · Requirement │
|
|
86
|
+
├───────────────────────────────────────────────────┤
|
|
87
|
+
│ 👥 Employee │
|
|
88
|
+
│ Memory · Personality · Skills · Lifecycle │
|
|
89
|
+
├───────────────────────────────────────────────────┤
|
|
90
|
+
│ 🤖 Agent │
|
|
91
|
+
│ LLM Agent · CLI Agent · Web Agent │
|
|
92
|
+
│ (Unified interface, zero business logic) │
|
|
93
|
+
└───────────────────────────────────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **Agent** — Pure LLM communication engine. Supports API, CLI, and Web backends behind a single `chat()` interface. Zero business logic.
|
|
97
|
+
- **Employee** — The atomic unit. Wraps an Agent with persistent memory, personality, skills, and autonomous poll-think-reply behavior.
|
|
98
|
+
- **Organization** — Company structure: departments, teams, group chats, requirements workflow.
|
|
99
|
+
- **Secretary** — Boss's AI assistant that understands intent, manages HR, and coordinates departments.
|
|
100
|
+
|
|
101
|
+
> 📖 See [ARCHITECTURE.md](ARCHITECTURE.md) for the full deep-dive — employee lifecycle, memory system design, flow-of-thought pipeline, anti-spam gates, and social memory details.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## ⬇ Download
|
|
106
|
+
|
|
107
|
+
Grab the latest release for your platform:
|
|
108
|
+
|
|
109
|
+
**[Download IdeaCo](https://github.com/ymssx/IdeaCo/releases/latest)**
|
|
110
|
+
|
|
111
|
+
| Platform | File |
|
|
112
|
+
|----------|------|
|
|
113
|
+
| macOS (Apple Silicon) | `IdeaCo-x.x.x-arm64.dmg` |
|
|
114
|
+
| macOS (Intel) | `IdeaCo-x.x.x-x64.dmg` |
|
|
115
|
+
| Windows | `IdeaCo-x.x.x-Setup.exe` |
|
|
116
|
+
| Linux | `IdeaCo-x.x.x.AppImage` / `.deb` |
|
|
117
|
+
|
|
118
|
+
<details>
|
|
119
|
+
<summary><b>macOS Security Notice</b></summary>
|
|
120
|
+
|
|
121
|
+
Since IdeaCo is not signed with an Apple Developer certificate, macOS will show a security warning. To open it:
|
|
122
|
+
|
|
123
|
+
1. **Right-click** the app → **Open** → **Open** again in the dialog
|
|
124
|
+
2. **Or**: System Settings → Privacy & Security → scroll down → **Open Anyway**
|
|
125
|
+
3. **Or via Terminal**: `xattr -cr /Applications/IdeaCo.app`
|
|
126
|
+
</details>
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🚀 Quick Start
|
|
131
|
+
|
|
132
|
+
### From Source
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
git clone https://github.com/ymssx/IdeaCo.git
|
|
136
|
+
cd IdeaCo
|
|
137
|
+
yarn install
|
|
138
|
+
yarn dev
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Open **http://localhost:9999** — the Setup Wizard will guide you.
|
|
142
|
+
|
|
143
|
+
### Docker
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
docker compose up -d
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Data is persisted via Docker volumes (`app-data`, `app-workspace`).
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## ⚙ Configuration
|
|
154
|
+
|
|
155
|
+
### LLM Providers
|
|
156
|
+
|
|
157
|
+
Configure via the Setup Wizard on first launch, or later through the **Brain Providers** page.
|
|
158
|
+
|
|
159
|
+
| Provider | Endpoint | Notes |
|
|
160
|
+
|----------|----------|-------|
|
|
161
|
+
| DeepSeek | [platform.deepseek.com](https://platform.deepseek.com) | Best cost-effectiveness |
|
|
162
|
+
| OpenAI | [platform.openai.com](https://platform.openai.com) | GPT-4o / GPT-4 |
|
|
163
|
+
| Anthropic | [console.anthropic.com](https://console.anthropic.com) | Claude 3.5 / 4 |
|
|
164
|
+
| Any OpenAI-compatible | Custom base URL | Ollama, vLLM, etc. |
|
|
165
|
+
|
|
166
|
+
### CLI Coding Backends
|
|
167
|
+
|
|
168
|
+
IdeaCo can dispatch coding tasks to local CLI assistants. Install any of these and they'll be auto-detected:
|
|
169
|
+
|
|
170
|
+
| Backend | Command | Description |
|
|
171
|
+
|---------|---------|-------------|
|
|
172
|
+
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | `claude` | Anthropic's AI coding assistant |
|
|
173
|
+
| [Codex](https://github.com/openai/codex) | `codex` | OpenAI's coding agent |
|
|
174
|
+
| [CodeBuddy](https://codebuddy.ai) | `codebuddy` | Tencent's AI coding assistant |
|
|
175
|
+
|
|
176
|
+
> No API key or CLI tool is strictly required — the system falls back to a built-in rule engine, but agents will only give mechanical responses.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 📁 Project Structure
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
IdeaCo/
|
|
184
|
+
├── src/
|
|
185
|
+
│ ├── app/ # Next.js App Router + API Routes
|
|
186
|
+
│ ├── components/ # React UI (Pixel Office, Group Chat, Dashboards...)
|
|
187
|
+
│ ├── core/ # Core engine
|
|
188
|
+
│ │ ├── agent/ # Agent layer (LLM / CLI / Web)
|
|
189
|
+
│ │ ├── employee/ # Employee layer (memory, lifecycle, skills)
|
|
190
|
+
│ │ ├── organization/ # Org layer (company, dept, team, HR)
|
|
191
|
+
│ │ ├── system/ # System services (audit, cron, plugins)
|
|
192
|
+
│ │ ├── prompts.js # All LLM prompt templates
|
|
193
|
+
│ │ └── requirement.js # Requirement workflow engine
|
|
194
|
+
│ ├── lib/ # Frontend utilities (Zustand store, i18n)
|
|
195
|
+
│ └── locales/ # i18n (zh/en/ja/ko/es/de/fr)
|
|
196
|
+
├── data/ # Runtime data (auto-created)
|
|
197
|
+
├── workspace/ # Agent-produced files per department
|
|
198
|
+
├── electron/ # Electron desktop app shell
|
|
199
|
+
└── package.json
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
[MIT](LICENSE)
|
package/bin/i18n.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import en from '../src/locales/en.js';
|
|
2
|
+
import zh from '../src/locales/zh.js';
|
|
3
|
+
import ja from '../src/locales/ja.js';
|
|
4
|
+
import ko from '../src/locales/ko.js';
|
|
5
|
+
import es from '../src/locales/es.js';
|
|
6
|
+
import fr from '../src/locales/fr.js';
|
|
7
|
+
import de from '../src/locales/de.js';
|
|
8
|
+
|
|
9
|
+
const translations = { en, zh, ja, ko, es, fr, de };
|
|
10
|
+
const DEFAULT_LANG = 'en';
|
|
11
|
+
|
|
12
|
+
function sanitiseLangToken(raw) {
|
|
13
|
+
if (!raw || typeof raw !== 'string') return null;
|
|
14
|
+
const trimmed = raw.trim();
|
|
15
|
+
if (!trimmed || trimmed === '*') return null;
|
|
16
|
+
return trimmed.toLowerCase().split('-')[0] || null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function resolveLang() {
|
|
20
|
+
const envLang = process.env.IDEACO_LANG
|
|
21
|
+
|| process.env.LC_ALL
|
|
22
|
+
|| process.env.LC_MESSAGES
|
|
23
|
+
|| process.env.LANG;
|
|
24
|
+
const code = sanitiseLangToken(envLang || '');
|
|
25
|
+
if (code && translations[code]) return code;
|
|
26
|
+
return DEFAULT_LANG;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getNestedValue(obj, key) {
|
|
30
|
+
return key.split('.').reduce((o, k) => o?.[k], obj);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createCliT() {
|
|
34
|
+
const lang = resolveLang();
|
|
35
|
+
return function t(key, params) {
|
|
36
|
+
let str = getNestedValue(translations[lang], key)
|
|
37
|
+
|| getNestedValue(translations[DEFAULT_LANG], key)
|
|
38
|
+
|| key;
|
|
39
|
+
if (params) {
|
|
40
|
+
Object.entries(params).forEach(([k, v]) => {
|
|
41
|
+
str = str.replace(new RegExp(`\\{${k}\\}`, 'g'), String(v));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return str;
|
|
45
|
+
};
|
|
46
|
+
}
|